我一直在用這個結構撞擊我的頭在牆上。我能夠縮小到我的代碼的realloc部分。Realloc:在結構中重置結構的可彎曲陣列
CalStatus readCalComp(FILE *const ics, CalComp **const pcomp)
{
CalStatus test;
CalProp * foldLine;
CalProp * temp;
CalComp ** subComp;
char * buffer;
static int depth = 0;
int count = 0;
int i = 0;
buffer = NULL;
foldLine = NULL;
subComp = NULL;
if (depth == 0)
{
test = readCalLine (ics, &buffer);
if (buffer == NULL)
{
return test;
}
foldLine = malloc (sizeof (CalProp));
assert (foldLine != NULL);
test.code = parseCalProp (buffer, foldLine);
free (buffer);
if ((strcmp ("BEGIN", foldLine->name) == 0) && ((strcmp ("VCALENDAR", foldLine->value) == 0)))
{
(*pcomp)->name = malloc (sizeof(char) * strlen(foldLine->value)+1);
assert ((*pcomp)->name != NULL);
strcpy((*pcomp)->name, foldLine->value);
depth = depth + 1;
free(foldLine->name);
free(foldLine->value);
free(foldLine);
while ((buffer != NULL) && (test.code == OK) && (depth > 0))
{
test = readCalLine (ics, &buffer);
if (buffer != NULL)
{
foldLine = malloc (sizeof(CalProp));
assert (foldLine != NULL);
test.code = parseCalProp (buffer, foldLine);
free (buffer);
if ((strcmp ("END", foldLine->name) == 0) && ((strcmp ("VCALENDAR", foldLine->value) == 0) || (strcmp ("VCALENDAR\r\n", foldLine->value) == 0)))
{
depth = depth - 1;
free(foldLine->name);
free(foldLine->value);
free(foldLine);
return test;
}
else if (strcmp ("BEGIN", foldLine->name) == 0)
{
subComp = malloc(sizeof (CalComp *));
*subComp = malloc(sizeof(CalComp) + (1*sizeof(CalComp*)));
(*subComp)-> name = NULL;
(*subComp)-> nprops = 0;
(*subComp)-> prop = NULL;
(*subComp)-> ncomps = 0;
(*subComp)-> comp[0] = NULL;
(*subComp)-> name = malloc(sizeof(char) *strlen(foldLine->value)+1);
strcpy((*subComp)->name, foldLine->value);
if ((*pcomp)-> ncomps == 0)
{
(*pcomp)->comp[(*pcomp)->ncomps] = *subComp;
(*pcomp)->ncomps += 1;
}
else
{
(*pcomp)->ncomps += 1;
*pcomp = realloc(*pcomp, sizeof(CalComp) + (2*sizeof(CalComp*)));
(*pcomp)->comp[(*pcomp)->ncomps-1] = *subComp;
}
depth = depth + 1;
test = readCalComp (ics, subComp);
}
} // end of if buffer NULL
}// end of While
} // end of if VCALENDAR
} // End of if Depth
else
{
if (count == 0)
{
test = readCalLine (ics, &buffer);
count += 1;
}
while ((test.code == OK) && (buffer != NULL))
{
if (count != 1)
{
test = readCalLine (ics, &buffer);
}
else
{
count = 0;
}
if (buffer != NULL)
{
foldLine = malloc (sizeof(CalProp));
test.code = parseCalProp (buffer, foldLine);
free (buffer);
if ((strcmp ("END", foldLine->name) == 0) && ((strcmp ((*pcomp)->name, foldLine->value) == 0)))
{
depth = depth - 1;
free (foldLine->name);
free (foldLine->value);
free (foldLine);
return test;
}
else if (strcmp ("BEGIN", foldLine->name) == 0)
{
printf("Success in malloc 2!\n");
subComp = malloc(sizeof (CalComp *));
*subComp = malloc(sizeof(CalComp) + (1*sizeof(CalComp*)));
(*subComp)-> name = NULL;
(*subComp)-> nprops = 0;
(*subComp)-> prop = NULL;
(*subComp)-> ncomps = 0;
(*subComp)-> comp[0] = NULL;
(*subComp)-> name = malloc(sizeof(char) *strlen(foldLine->value)+1);
strcpy ((*subComp)->name, foldLine->value);
if ((*pcomp)-> ncomps == 0)
{
(*pcomp)->comp[(*pcomp)->ncomps] = *subComp;
(*pcomp)->ncomps += 1;
}
else
{
(*pcomp)->ncomps += 1;
(*pcomp) = realloc(*pcomp, sizeof(CalComp) + (2*sizeof(CalComp*)));
(*pcomp)->comp[(*pcomp)->ncomps-1] = *subComp;
printf ("First subcomponent is %s\n", (*pcomp)->comp[0]->name);
printf ("Second subcomponent is %s\n", (*pcomp)->comp[1]->name);
}
depth = depth + 1;
test = readCalComp (ics, subComp);
}
}
}
}
return test;
}
CalComp系統是由一個結構:
char * name;
int numProps;
CalProp *prop (linked list);
int numComp;
CalComp *comp[] (flexible array);
檢查函數內部,靈活的陣列內的結構的名稱是正確的,但是當我嘗試訪問外部的名字函數,它可以是NULL值,也可以設置爲結構的第一個鏈表節點的名稱。
由於賦值的性質,我無法修改Calcomp結構和函數參數。函數必須是遞歸的,並且靈活數組必須根據需要進行調整。
正如我之前所說的,我通過打印靈活數組中的值來縮小到realloc範圍。程序重新分配時發生該錯誤。我試圖重新分配到一個臨時變量,檢查是否爲NULL,然後將其分配給pcomp但沒有幫助。
你有很多重複的代碼初始化'CalComp'和'CalProp'。在處理結構時,我總是寫一個'structname_new'和一個'structname_destroy'來封裝那些代碼中有時候很棘手的部分。嘗試這樣做,看看這是否更容易調試。如果沒有,請使用更好的封裝代碼重新發布您的問題。 – Schwern
我只想提一提,所有可用的函數都會導致包含END的靈活數組名稱。 – Mog
我想清楚是什麼導致了這個問題。當我在遞歸調用中使用realloc時,它可能會更改內存地址位置。由於遞歸調用,沒有任何東西可以捕獲父節點中地址的變化。因此它充滿了垃圾。人很煩人。通過使用靜態幫助函數來固定地址,並在遞歸調用返回後將其放回。 – Mog