我目前正在学习C并尝试使用程序调试问题。
我已经将代码片段分成了一个单独的测试程序,并设法复制了故障,但我无法看到我的生活中出错的地方。我认为我最有可能在某个地方搞砸指针,但不确定在哪里。
以下是我的代码:
typedef int BOOL;
#define TRUE 1
#define FALSE 0
typedef struct CallLogSearchDataStruct
{
char * target;
float duration;
struct CallLogSearchOutboundStruct * outboundLegs;
} callLogSearchDataStruct;
typedef struct CallLogSearchOutboundStruct
{
char * target;
float duration;
BOOL allowOverwrite;
struct CallLogSearchOutboundStruct *nextLeg;
} callLogSearchOutboundStruct;
callLogSearchOutboundStruct *insertOutboundLegtoList(callLogSearchOutboundStruct ** outboundLeg, char * target, float duration, BOOL overwriteFirstoutboundLegs);
void freeCallLogSearchDataStruct(callLogSearchDataStruct *callLogSearchData, int count);
void clearOutboundLinkedList(callLogSearchOutboundStruct **outboundLeg);
/*
*
*/
int main(int argc, char** argv) {
int i = 0;
int count = 10;
callLogSearchOutboundStruct * outboundCallLegStartPtr = NULL;
callLogSearchDataStruct * callLogSearchData = NULL;
callLogSearchData = calloc(count, sizeof(callLogSearchDataStruct));
for (i = 0; i < 10; i++)
{
asprintf(&callLogSearchData[i].target, "Target %i", i);
callLogSearchData[i].duration = i * 10;
callLogSearchData[i].outboundLegs = malloc(sizeof(callLogSearchOutboundStruct));
callLogSearchData[i].outboundLegs->target = NULL;
callLogSearchData[i].outboundLegs->nextLeg = NULL;
outboundCallLegStartPtr = callLogSearchData[i].outboundLegs;
insertOutboundLegtoList(&outboundCallLegStartPtr, "OutboundTarget", i, FALSE);
}
freeCallLogSearchDataStruct(callLogSearchData, count);
free(callLogSearchData);
return (EXIT_SUCCESS);
}
callLogSearchOutboundStruct *insertOutboundLegtoList(callLogSearchOutboundStruct ** outboundLeg, char * target, float duration, BOOL overwriteFirstoutboundLegs)
{
if (target == NULL)
{
return *outboundLeg;
}
if (!*outboundLeg)
{
callLogSearchOutboundStruct *newOutboundLeg = NULL;
newOutboundLeg = malloc(sizeof(*newOutboundLeg));
newOutboundLeg->nextLeg = NULL;
newOutboundLeg->target = strdup(target);
newOutboundLeg->duration = duration;
newOutboundLeg->allowOverwrite = FALSE;
*outboundLeg = newOutboundLeg;
return newOutboundLeg;
}
if (overwriteFirstoutboundLegs == TRUE)
{
callLogSearchOutboundStruct * currentLeg = *outboundLeg;
callLogSearchOutboundStruct * temp;
free(currentLeg->target);
currentLeg->target = strdup(target);
currentLeg->duration = duration;
currentLeg->allowOverwrite = FALSE;
temp = currentLeg->nextLeg;
while (temp)
{
temp->allowOverwrite = TRUE;
temp = temp->nextLeg;
}
return currentLeg;
}
else
{
callLogSearchOutboundStruct **ptr = outboundLeg;
callLogSearchOutboundStruct *currentLeg = *outboundLeg;
if (currentLeg->target == NULL)
{
//This strdup is causing the loss record
currentLeg->target = strdup(target);
currentLeg->duration = duration;
currentLeg->allowOverwrite = FALSE;
*ptr = currentLeg;
return currentLeg;
}
else
{
while (currentLeg && currentLeg->allowOverwrite == FALSE)
{
ptr = ¤tLeg->nextLeg;
currentLeg = currentLeg->nextLeg;
}
if (currentLeg)
{
currentLeg->target = strdup(target);
currentLeg->duration = duration;
currentLeg->allowOverwrite = FALSE;
*ptr = currentLeg;
return currentLeg;
}
else
{
currentLeg = malloc(sizeof(*currentLeg));
currentLeg->nextLeg = NULL;
currentLeg->target = strdup(target);
currentLeg->allowOverwrite = FALSE;
currentLeg->duration = duration;
*ptr = currentLeg;
}
}
return currentLeg;
}
}
void freeCallLogSearchDataStruct(callLogSearchDataStruct *callLogSearchData, int count)
{
int i = 0;
for (i = 0; i < count; i++)
{
if (callLogSearchData[i].outboundLegs != NULL)
{
clearOutboundLinkedList(&callLogSearchData[i].outboundLegs);
free(callLogSearchData[i].outboundLegs);
}
free(callLogSearchData[i].target);
}
}
void clearOutboundLinkedList(callLogSearchOutboundStruct **outboundLeg)
{
callLogSearchOutboundStruct *currentStruct = *outboundLeg;
callLogSearchOutboundStruct *temp;
while (currentStruct->nextLeg != NULL)
{
temp = currentStruct;
currentStruct = currentStruct->nextLeg;
free(temp->target);
free(temp);
}
}
以下是valgrind的输出
==10626== HEAP SUMMARY:
==10626== in use at exit: 150 bytes in 10 blocks
==10626== total heap usage: 41 allocs, 31 frees, 1,520 bytes allocated
==10626==
==10626== Searching for pointers to 10 not-freed blocks
==10626== Checked 47,612 bytes
==10626==
==10626== 150 bytes in 10 blocks are definitely lost in loss record 1 of 1
==10626== at 0x40072D5: malloc (vg_replace_malloc.c:291)
==10626== by 0xB0798F: strdup (in /lib/libc-2.12.so)
==10626== by 0x80486F9: insertOutboundLegtoList (main.c:115)
==10626== by 0x80485BA: main (main.c:55)
==10626==
==10626== LEAK SUMMARY:
==10626== definitely lost: 150 bytes in 10 blocks
==10626== indirectly lost: 0 bytes in 0 blocks
==10626== possibly lost: 0 bytes in 0 blocks
==10626== still reachable: 0 bytes in 0 blocks
==10626== suppressed: 0 bytes in 0 blocks
==10626==
==10626== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 12 from 8)
从代码中的注释中可以看出,我检查currentLeg-&gt; target是否为NULL,如果是这样的话,我将char *强制转换为此变量,但Valgrind报告此strdup丢失但我看不到怎么样。由于计数器的缘故,我只能写一次,而我正在释放结构,所以不知道在哪里看。
感谢您提供的任何帮助。
答案 0 :(得分:1)
我想我找到了你的问题,就在这个代码示例中:
`
if (currentLeg)
{
currentLeg->target = strdup(target);
currentLeg->duration = duration;
currentLeg->allowOverwrite = FALSE;
*ptr = currentLeg;
return currentLeg;
}
`
事实上,当你遇到这种情况时,你的currentLeg已经将其目标链接到一个duuped char *数组,最好检查currentLeg->target != NULL
是否然后释放它:
`
if (currentLeg)
{
if (currentLeg->target != NULL)
free(currentLeg->target);
currentLeg->target = strdup(target);
currentLeg->duration = duration;
currentLeg->allowOverwrite = FALSE;
*ptr = currentLeg;
return currentLeg;
}
`
修改:我找到并修补了您的错误:
更改强>
`
if (callLogSearchData[i].outboundLegs != NULL)
{
clearOutboundLinkedList(&callLogSearchData[i].outboundLegs);
free(callLogSearchData[i].outboundLegs);
}
`
以强>
`
if (callLogSearchData[i].outboundLegs != NULL)
{
clearOutboundLinkedList(&callLogSearchData[i].outboundLegs);
}
`
并将 while (currentStruct->nextLeg != NULL)
更改为 while (currentStruct != NULL)
实际上,链接列表的en从未正确释放
(对不起,我的英文不好)