在一个结构内的结构内strdup一个char*,导致valgrind中的丢失
我目前正在学习C语言,并试图用程序调试一个问题 我已经将代码片段放入了一个单独的测试程序中,并成功地复制了错误,但我一辈子都看不出哪里出了问题。我想我很可能在某个地方把指针弄坏了,但不确定在哪里 下面是我的代码:在一个结构内的结构内strdup一个char*,导致valgrind中的丢失,c,C,我目前正在学习C语言,并试图用程序调试一个问题 我已经将代码片段放入了一个单独的测试程序中,并成功地复制了错误,但我一辈子都看不出哪里出了问题。我想我很可能在某个地方把指针弄坏了,但不确定在哪里 下面是我的代码: typedef int BOOL; #define TRUE 1 #define FALSE 0 typedef struct CallLogSearchDataStruct { char * target; float duration; struct Ca
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);
}
}
正如您可以从代码中的注释中看到的,我检查currentLeg->target是否为NULL,如果为NULL,我在这个变量中添加了一个char*,但是Valgrind报告说这个strdup丢失了,但我看不出是怎么做的。由于计数器的原因,我只能给它写一次,我正在释放结构,所以不确定要去哪里看 我想我发现了您的问题,它就在这个代码示例中:
`
if (currentLeg)
{
currentLeg->target = strdup(target);
currentLeg->duration = duration;
currentLeg->allowOverwrite = FALSE;
*ptr = currentLeg;
return currentLeg;
}
`
事实上,在这种情况下,currentLeg已经将其目标链接到duuped char*数组,最好检查currentLeg->target!=空,然后释放它:
`
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从未正确释放
(顺便说一句,很抱歉我的英语不好)读的太多了!!。。。请尽量使它更简洁,这是考虑周到的。我已经指出了问题所在,我正在向您展示我在哪里释放结构,在我看来,您需要看到我在哪里分配和释放结构,以便能够提供帮助我没有遵循所有的逻辑,但是while(currentStruct->nextLeg!=NULL)
在你的上一个函数中,它看起来很可疑-它永远不会释放列表中的最后一个节点。从某种意义上说,谢谢你的权利,这会给我带来另一个问题,尽管我认为这部分代码目前实际上没有被使用。无论如何,我已经添加了它并重建了它,但是我仍然在上面的if语句中从Valgrind得到了相同的错误。这正常吗?你从来没有进入while(currentStruct->nextLeg!=NULL)
?谢谢你是对的,循环是问题所在,我保持了while循环不变,但是在循环之后我释放了(currentStruct)然后Valgrind说在我的头脑中没有错误,这是过度的解决方案。。;很高兴你找到了!
`
if (callLogSearchData[i].outboundLegs != NULL)
{
clearOutboundLinkedList(&callLogSearchData[i].outboundLegs);
}
`