2017-10-14 135 views
0

我的代碼工作正常,直到我嘗試釋放分配的內存。我malloc編輯files指針,後來我用realloc來增加大小。但是當我嘗試釋放內存時,它給了我無效的指針錯誤,不知道爲什麼。不能釋放C中的重新分配內存

char *files = malloc(1); 
char *temp = strdup(argv[i]); 
strcat(temp, "/"); 
strcat(temp, dp->d_name); 
DIR *child_dir; 
child_dir = opendir (temp); 

if (child_dir == NULL) { 
    files = realloc(files, strlen(dp->d_name)+1); 
    strcat(files, dp->d_name); 
    strcat(files, "/"); 
} else { 
    struct dirent *child_dp; 
    while ((child_dp = readdir (child_dir)) != NULL) { 
     if (!strcmp(child_dp->d_name, ".") 
      || !strcmp(child_dp->d_name, "..")) 
       continue; 

     files = realloc(files, strlen(child_dp->d_name) + 1); 
     strcat(files, child_dp->d_name); 
     strcat(files, "/"); 
    } 
} 
close(fd[0]); 
int n = write(fd[1], files, strlen(files)); 
free(temp); // free 
free(files); // free 
temp = NULL; 
files = NULL; 
return; 

這是我得到的錯誤,

======= Backtrace: ========= 
/lib64/libc.so.6(+0x721af)[0x7fa2e697c1af] 
/lib64/libc.so.6(+0x77706)[0x7fa2e6981706] 
/lib64/libc.so.6(+0x78453)[0x7fa2e6982453] 
./myfind[0x40110c] 
./myfind[0x400b02] 
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7fa2e692a6e5] 
./myfind[0x400a09] 
======= Memory map: ======== 

注:如果我沒有釋放任何內存空間中運行相同的代碼,它工作正常。這意味着指針指向內存中的正確位置。

+2

當你執行'strcat(temp,「/」);'時,你會導致未定義的行爲。 'temp'對於你複製的'argv [i]'字符串來說只有足夠大的空間,它沒有空間給你連接額外的字符串。 – Barmar

回答

2

你使用此代碼破壞您的堆:

char *temp = strdup(argv[i]); 
strcat(temp, "/"); 
strcat(temp, dp->d_name); 

strdup只爲它的複製字符串分配足夠的空間,但你更串聯到年底沒有重新分配,以騰出空間。

你還沒有爲NUL終止符留出空間,當你reallocfilesif條件,但在大多數情況下,你會得逞的(你應該儘管分配正確的量)。

最後,在while環路else箱子,每個realloc只分配足夠你要添加的東西,但是對於已經存在的東西沒有留出空間(並再次,沒有剩餘空間可用於NUL終止) 。重複的濫用在一段時間後會保證堆腐敗。

+1

*「在大多數情況下,你會擺脫這種情況」*,我不確定這可能不會留下錯誤的印象......也許括號內的內容應該閱讀(*「如果您未能分配正確的內存 - 你應該被槍殺!「),或者可能只是*」 - 未定義的行爲結果「*':)' –

+0

@ DavidC.Rankin:是的,我只是指出有些錯誤往往不會在一些或所有編譯器/系統上導致症狀,所以「它的工作原理」並不足以說明代碼是正確的。 – ShadowRanger

+0

是的,我明白了你所說的癥結所在,在這個星期五的晚上,這讓我覺得有點奇怪/幽默(因此':''' –