我目前正在开发一个项目,我正在使用valgrind来查找内存泄漏,我在尝试找到它们时遇到了一些麻烦。
我做了一个小小的应用程序来模拟问题所在,我设法复制了我在valgrind中看到的错误。
以下是我的主要功能:
int main(int argc, char** argv) {
inboundStruct * inboundDataStruct = NULL;
outboundStruct * outboundDataStruct = NULL;
char *outboundName = NULL;
if (mallocInboundStruct(&inboundDataStruct, 2))
{
printf("Error malloc'ing inbound struct\n");
exit(1);
}
int i = 0;
for (i = 0; i < 2; i++)
{
inboundDataStruct[i].index = i;
asprintf(&inboundDataStruct[i].itemName, "Item %i", i);
mallocOutboundStruct(&inboundDataStruct[i].outboundLeg);
if (outboundDataStruct == NULL)
{
outboundDataStruct = inboundDataStruct[i].outboundLeg;
}
asprintf(&outboundName, "Outbound Target %i", i);
insertOutboundLeg(&outboundDataStruct, outboundName, i);
outboundDataStruct = NULL;
free(outboundName);
outboundName = NULL;
}
printStructure(inboundDataStruct, 2);
clearOutboundLinkedList(&outboundDataStruct);
freeInboundStruct(&inboundDataStruct, 2);
return (EXIT_SUCCESS);
}
下面是入站结构的malloc函数
int mallocInboundStruct(inboundStruct **inboundDataStruct, int size)
{
int i = 0;
inboundStruct *tempStruct = NULL;
tempStruct = (inboundStruct*)malloc(size * sizeof(inboundStruct));
if (tempStruct != NULL)
{
for (i = 0; i < size; i++)
{
tempStruct[i].index = i;
tempStruct[i].itemName = NULL;
}
*inboundDataStruct = tempStruct;
return 0;
}
return 1;
}
下面是我的malloc for outbound struct
int mallocOutboundStruct(outboundStruct **outboundDataStruct)
{
outboundStruct *tempStruct = NULL;
tempStruct = (outboundStruct*)malloc(sizeof(outboundStruct));
if (tempStruct != NULL)
{
tempStruct->index = 0;
tempStruct->nextLeg = NULL;
tempStruct->outboundName = NULL;
*outboundDataStruct = tempStruct;
return 0;
}
return 1;
}
下面没有入站结构
int freeInboundStruct(inboundStruct **inboundDataStruct, int size)
{
inboundStruct *tempStruct = *inboundDataStruct;
int i = 0;
for (i = 0; i < size; i++)
{
free(tempStruct[i].itemName);
tempStruct[i].itemName = NULL;
}
free(tempStruct);
return 0;
}
以下是释放出站结构
int clearOutboundLinkedList(outboundStruct **outboundDataStruct)
{
outboundStruct *currentStruct = *outboundDataStruct;
outboundStruct *temp;
if (currentStruct == NULL)
{
return 0;
}
while (currentStruct->nextLeg != NULL)
{
temp = currentStruct;
currentStruct = currentStruct->nextLeg;
free(temp->outboundName);
temp->outboundName = NULL;
free(temp);
}
free(currentStruct->outboundName);
currentStruct->outboundName = NULL;
free(currentStruct);
currentStruct = NULL;
return 0;
}
最后是将数据插入出站结构
的函数void insertOutboundLeg(outboundStruct ** outboundDataStruct, char * outboundName, int index)
{
outboundStruct **ptr = outboundDataStruct;
outboundStruct *currentLeg = *outboundDataStruct;
if (currentLeg->outboundName == NULL)
{
currentLeg->index = index;
//asprintf(¤tLeg->outboundName, "Item %s-%i", outboundName, index);
currentLeg->outboundName = strdup(outboundName);
*ptr = currentLeg;
}
else
{
while (currentLeg)
{
ptr = ¤tLeg->nextLeg;
currentLeg = currentLeg->nextLeg;
}
if (currentLeg)
{
if (currentLeg->outboundName != NULL)
{
free(currentLeg->outboundName);
currentLeg->outboundName = NULL;
}
//asprintf(¤tLeg->outboundName, "Item %s-%i", outboundName, index);
currentLeg->outboundName = strdup(outboundName);
currentLeg->index = index;
*ptr = currentLeg;
}
else
{
currentLeg = malloc(sizeof(*currentLeg));
currentLeg->nextLeg = NULL;
//asprintf(¤tLeg->outboundName, "Item: %s-%i", outboundName, index);
currentLeg->outboundName = strdup(outboundName);
currentLeg->index = index;
*ptr = currentLeg;
}
}
}
当我通过valgrind运行应用程序时,它给出了以下输出:
> ==32080== Command: ./mallocTest
> ==32080== Index: 0 Item: Item 0
> Index: 0 Item: Outbound Target 0 Index: 0 Item: Item 1
> Index: 1 Item: Outbound Target 1
> ==32080==
> ==32080== HEAP SUMMARY:
> ==32080== in use at exit: 60 bytes in 4 blocks
> ==32080== total heap usage: 13 allocs, 9 frees, 534 bytes allocated
> ==32080==
> ==32080== 36 bytes in 2 blocks are indirectly lost in loss record 1 of 2
> ==32080== at 0x40072D5: malloc (vg_replace_malloc.c:291)
> ==32080== by 0xB0798F: strdup (in /lib/libc-2.12.so)
> ==32080== by 0x804869D: insertOutboundLeg (main.c:86)
> ==32080== by 0x80485FF: main (main.c:38)
> ==32080==
> ==32080== 60 (24 direct, 36 indirect) bytes in 2 blocks are definitely lost in loss record 2 of 2
> ==32080== at 0x40072D5: malloc (vg_replace_malloc.c:291)
> ==32080== by 0x80488A4: mallocOutboundStruct (main.c:157)
> ==32080== by 0x80485A3: main (main.c:31)
> ==32080==
> ==32080== LEAK SUMMARY:
> ==32080== definitely lost: 24 bytes in 2 blocks
> ==32080== indirectly lost: 36 bytes in 2 blocks
> ==32080== possibly lost: 0 bytes in 0 blocks
> ==32080== still reachable: 0 bytes in 0 blocks
> ==32080== suppressed: 0 bytes in 0 blocks
> ==32080==
> ==32080== For counts of detected and suppressed errors, rerun with: -v
> ==32080== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 8)
我认为问题可能出在我的insertOutboundLeg
,但我看不出原因。我是C的新手,我正在学习它。
答案 0 :(得分:0)
Valgrind告诉你丢失的内存在哪里分配;它无法告诉你内存何时无法访问。问题通常不在于分配,而在于之后如何处理分配的内存。
在您的情况下,第一个丢失记录告诉您通过调用insertOutboundLeg()
在strdup()
中分配的一块内存被泄露。我没有行号来指导我,但看起来它必须是
currentLeg->outboundName = strdup(outboundName);
请记住,strdup()
始终会分配调用者负责释放的内存。我看到你在函数clearOutboundLinkedList()
中正确地释放了这个成员,所以它必须是outboundStruct
某处超出范围或被释放而不被该函数处理。
仔细观察,然后,我看到您的main()
函数调用mallocOutboundStruct()
两次,在变量outboundDataStruct
中保留结果指针中的一个。之后通过clearOutboundLinkedList()
释放了一个,但另一个永远不会。事实上,另一个根本没有被释放,这似乎是第二次失败记录的主题。