首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用DnsGetCacheDataTable时内存泄漏

使用DnsGetCacheDataTable时内存泄漏
EN

Stack Overflow用户
提问于 2015-08-08 05:27:02
回答 2查看 2.1K关注 0票数 4

下面的代码显示DNS客户端中缓存的域名。当内存泄漏发生在int stat = DnsGetCacheDataTable(pEntry);行时,有人能帮我找到它吗?

PS:编译代码时请使用DNSAPI.lib。

代码语言:javascript
复制
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <WinDNS.h>
#include <stdarg.h>
typedef struct _DNS_CACHE_ENTRY {
    struct _DNS_CACHE_ENTRY* pNext; // Pointer to next entry
    PWSTR pszName; // DNS Record Name
    unsigned short wType; // DNS Record Type
    unsigned short wDataLength; // Not referenced
    unsigned long dwFlags; // DNS Record FlagsB
} DNSCACHEENTRY, *PDNSCACHEENTRY;

typedef int(WINAPI *DNS_GET_CACHE_DATA_TABLE)(PDNSCACHEENTRY);
void UpdateDNS(void)
{

    PDNSCACHEENTRY pEntry = (PDNSCACHEENTRY) malloc(sizeof(DNSCACHEENTRY));
    // Loading DLL
    HINSTANCE hLib = LoadLibrary(TEXT("DNSAPI.dll"));
    // Get function address
    DNS_GET_CACHE_DATA_TABLE DnsGetCacheDataTable = (DNS_GET_CACHE_DATA_TABLE) GetProcAddress(hLib, "DnsGetCacheDataTable");
    int stat = DnsGetCacheDataTable(pEntry);
    printf("stat = %d\n", stat);
    pEntry = pEntry->pNext;
    while (pEntry) {
        wprintf(L"%s : %d \n", (pEntry->pszName), (pEntry->wType));
        pEntry = pEntry->pNext;
    }
    free(pEntry);
}

int main(int argc, char **argv) {

    while (TRUE)
    {
        Sleep(100);
        UpdateDNS();
    }   
    return 0;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-08 11:49:09

尝试使用Deleaker,因为乍一看,代码看起来很好:

然后开始调试..。当然还有!您释放的不是原始的pEntry,而是修改的一个。

在这里,更正的代码:

代码语言:javascript
复制
void UpdateDNS(void)
{

    PDNSCACHEENTRY pEntry = (PDNSCACHEENTRY) malloc(sizeof(DNSCACHEENTRY) + 0x10000);
    PDNSCACHEENTRY pFirstEntry = pEntry;
    // Loading DLL
    HINSTANCE hLib = LoadLibrary(TEXT("DNSAPI.dll"));
    // Get function address
    DNS_GET_CACHE_DATA_TABLE DnsGetCacheDataTable = (DNS_GET_CACHE_DATA_TABLE) GetProcAddress(hLib, "DnsGetCacheDataTable");
    int stat = DnsGetCacheDataTable(pEntry);
    printf("stat = %d\n", stat);
    pEntry = pEntry->pNext;
    while (pEntry) {
        wprintf(L"%s : %d \n", (pEntry->pszName), (pEntry->wType));
        pEntry = pEntry->pNext;
    }
    free(pFirstEntry);
}

UPDATE:实际上,您不需要分配任何内存,因为DnsGetCacheDataTable本身就分配了它。试图使用DnsRecordListFree释放内存,但似乎不起作用。仍有泄漏:

最后,我得到了不会泄漏的代码:

代码语言:javascript
复制
typedef int(WINAPI *DNS_GET_CACHE_DATA_TABLE)(PDNSCACHEENTRY*);

typedef void (WINAPI *P_DnsApiFree)(PVOID pData);

void UpdateDNS(void)
{
    PDNSCACHEENTRY pEntry = NULL;
    // Loading DLL
    HINSTANCE hLib = LoadLibrary(TEXT("DNSAPI.dll"));
    // Get function address
    DNS_GET_CACHE_DATA_TABLE DnsGetCacheDataTable = (DNS_GET_CACHE_DATA_TABLE)GetProcAddress(hLib, "DnsGetCacheDataTable");
    P_DnsApiFree pDnsApiFree = (P_DnsApiFree)GetProcAddress(hLib, "DnsApiFree");
    int stat = DnsGetCacheDataTable(&pEntry);
    PVOID pFirstEntry = pEntry;
    printf("stat = %d\n", stat);
    pEntry = pEntry->pNext;
    while (pEntry) {
        wprintf(L"%s : %d \n", (pEntry->pszName), (pEntry->wType));
        pDnsApiFree(pEntry->pszName);
        PVOID p = pEntry;
        pEntry = pEntry->pNext;
        pDnsApiFree(p);
    }
}
票数 2
EN

Stack Overflow用户

发布于 2015-08-08 06:51:04

这个代码有几个问题。

假设您在开始时调用LoadLibrary,而不是在结束时调用FreeLibrary。虽然技术上不是内存泄漏,但这可能不是最聪明的想法.

考虑一下,通过在循环之前直接移动到pEntry->pNext,您将跳过一个条目。当您对malloc返回的值赋值时,内存泄漏发生在同一代码行中。

代码语言:javascript
复制
PDNSCACHEENTRY pEntry = (PDNSCACHEENTRY) malloc(sizeof(DNSCACHEENTRY));
/* ... */
pEntry = pEntry->pNext;

您甚至不需要malloc,但更糟糕的是,您应该只返回malloc返回的free值,这样做是错误的:

代码语言:javascript
复制
free(pEntry);

事实上,您不仅不需要malloc (或free)来实现这一点,而且您需要的实际上是DnsRecordListFree

下面是您的代码应该是什么样子:

代码语言:javascript
复制
PDNS_RECORD entry;
HINSTANCE hLib = LoadLibrary(TEXT("DNSAPI.dll"));
DNS_GET_CACHE_DATA_TABLE DnsGetCacheDataTable = (DNS_GET_CACHE_DATA_TABLE) GetProcAddress(hLib, "DnsGetCacheDataTable");
int stat = DnsGetCacheDataTable(&entry);
printf("stat = %d\n", stat);
for (DNSCACHEENTRY *pTemp = &entry; pTemp; pTemp = pTemp->pNext) {
    wprintf(L"%s : %d \n", pTemp->pszName, pTemp->wType);
}
DnsRecordListFree(entry, DnsFreeRecordList);
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31889957

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档