结构和链表内存分配valgrind错误
Structure and Linked List memory allocation valgrind error
我目前正在做一个项目,在这个项目中我使用 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
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 的新手,并且正在学习它。
Valgrind 告诉您丢失的内存分配到哪里;它无法告诉您该内存在哪里无法访问。问题通常不在于分配,而在于之后如何处理分配的内存。
在您的情况下,第一个丢失记录告诉您通过调用 strdup()
在 insertOutboundLeg()
中分配的一块内存已泄漏。我没有行号来指导我,但看起来那必须是
的几次出现之一
currentLeg->outboundName = strdup(outboundName);
请始终记住,strdup()
分配调用者负责释放的内存。我看到你在你的函数 clearOutboundLinkedList()
中正确地释放了这个成员,所以一定是 outboundStruct
某个地方超出了范围或者在没有被该函数处理的情况下被释放。
仔细观察,然后,我看到您的 main()
函数调用了 mallocOutboundStruct()
两次,并在变量 [=18] 中保留 恰好一个 结果指针=].那个后来通过 clearOutboundLinkedList()
被释放,但另一个从未被释放。事实上,另一个从未被释放根本,这似乎是第二个损失记录的主题。
我目前正在做一个项目,在这个项目中我使用 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
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 的新手,并且正在学习它。
Valgrind 告诉您丢失的内存分配到哪里;它无法告诉您该内存在哪里无法访问。问题通常不在于分配,而在于之后如何处理分配的内存。
在您的情况下,第一个丢失记录告诉您通过调用 strdup()
在 insertOutboundLeg()
中分配的一块内存已泄漏。我没有行号来指导我,但看起来那必须是
currentLeg->outboundName = strdup(outboundName);
请始终记住,strdup()
分配调用者负责释放的内存。我看到你在你的函数 clearOutboundLinkedList()
中正确地释放了这个成员,所以一定是 outboundStruct
某个地方超出了范围或者在没有被该函数处理的情况下被释放。
仔细观察,然后,我看到您的 main()
函数调用了 mallocOutboundStruct()
两次,并在变量 [=18] 中保留 恰好一个 结果指针=].那个后来通过 clearOutboundLinkedList()
被释放,但另一个从未被释放。事实上,另一个从未被释放根本,这似乎是第二个损失记录的主题。