【问题标题】:Memory allocation/freeing error (extremely small code)内存分配/释放错误(极小的代码)
【发布时间】:2026-02-20 02:20:03
【问题描述】:

在运行最后列出的代码时,我在最后一行 FREE(pTcpTable); 处中断,如果我继续,则会出现此错误:

“netMon.exe 中 0x7737096E (ntdll.dll) 处的未处理异常:0xC0000005:访问冲突读取位置 0x00000009。”

crt0dat.c 打开并显示以下代码:

void __cdecl __crtExitProcess (
        int status
        )
{
        __crtCorExitProcess(status);

        /*
         * Either mscoree.dll isn't loaded,
         * or CorExitProcess isn't exported from mscoree.dll,
         * or CorExitProcess returned (should never happen).
         * Just call ExitProcess.
         */

        ExitProcess(status);
}

这是代码:

#include <iostream>
#include <WinSock2.h>
#include <IPHlpApi.h>
#include <Ws2tcpip.h>

using namespace std;

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))

int __cdecl main()
{
    PMIB_TCPTABLE_OWNER_PID pTcpTable;
    DWORD tcpTableSize = 0;

    char szLocalAddr[128];

    struct in_addr IpAddr;

    pTcpTable = (PMIB_TCPTABLE_OWNER_PID)MALLOC(sizeof(MIB_TCPTABLE_OWNER_PID));

    if(pTcpTable == NULL)
        return 1;

    tcpTableSize = sizeof(MIB_TCPTABLE_OWNER_PID);

    if(GetExtendedTcpTable(pTcpTable, &tcpTableSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS, 0) == ERROR_INSUFFICIENT_BUFFER)
    {
        FREE(pTcpTable);

        pTcpTable = (PMIB_TCPTABLE_OWNER_PID)MALLOC(sizeof(tcpTableSize));

        if(pTcpTable == NULL)
            return 1;
    }

    if(GetExtendedTcpTable(pTcpTable, &tcpTableSize, FALSE, AF_INET, TCP_TABLE_OWNER_PID_CONNECTIONS, 0) == NO_ERROR)
    {
        for(DWORD i = 0; i < pTcpTable->dwNumEntries; i++)
        {
            IpAddr.S_un.S_addr = (u_long)pTcpTable->table[i].dwRemoteAddr;

            InetNtop(AF_INET, &IpAddr, szLocalAddr, 128);
        }
    }

    if(pTcpTable != NULL)
        FREE(pTcpTable);

    return 0;
}

我不知道这里出了什么问题,它的内存分配和释放很简单,请帮帮我!

【问题讨论】:

  • Valgrind 非常擅长捕捉此类内容。

标签: c++ c winapi memory-management malloc


【解决方案1】:

我很确定你不想要这个:

    pTcpTable = (PMIB_TCPTABLE_OWNER_PID)MALLOC(sizeof(tcpTableSize));

而是

    pTcpTable = (PMIB_TCPTABLE_OWNER_PID)MALLOC(tcpTableSize);
    //                                          ^^^^^ sizeof removed.

它几乎肯定会崩溃,因为您覆盖了操作系统在退出时清理堆所必需的其他内容,这就是您在访问地址 9 时遇到崩溃的原因。

【讨论】:

  • 谢谢,这就是问题所在,我不知道我是怎么忽略了这一点……尽管连续 8 小时的编程可以对你做到这一点!
【解决方案2】:

问题来了

pTcpTable = (PMIB_TCPTABLE_OWNER_PID)MALLOC(**sizeof**(tcpTableSize));

你需要分配 tcpTableSize 字节,而不是 sizeof(DWORD)

【讨论】: