2017-10-14 15 views
0

할당 된 메모리를 해제 할 때까지 내 코드가 제대로 작동합니다. I mallocfiles 포인터를 편집 한 후 나중에 크기를 늘리기 위해 realloc을 사용했습니다. 그런데 왜 메모리를 해제하려고 할 때 잘못된 포인터 오류를 발생시킵니다. 그 이유는 확실하지 않습니다. C에서 Realloc 할당 된 메모리를 해제 할 수 없습니다

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 만이 복제 년대 문자열을 충분한 공간을 할당하지만 당신은 그 공간을 만들기 위해 재 할당하지 않고 마지막에 두 개를 연결할. 대부분의 경우에 당신이 떨어져 그와거야하지만 당신이 if 상태 reallocfiles, (당신이 비록 정확한 금액을 할당해야) 할 때

는 또한 NUL 종결을위한 공간을 떠나지 않을 것입니다.

마지막으로, else가지 경우 while 루프에서 각 realloc은 당신이 추가하는 물건에 대한 충분한 할당하지만, 이미 존재하는 무엇을위한 공간을 떠나지 않을 (다시, 더 공간이 NUL 종료 방치되지 않음)된다 . 반복되는 오용은 잠시 후 힙 손상을 보장합니다.

+1

* "대부분의 경우에"*, 나는 그것이 잘못된 인상을 남기지 않을지 모르겠다. .... 어쩌면 괄호로 묶어서는 안된다. - 당신은 총에 맞아야합니다! "*), 아니면 그냥 *"- 정의되지 않은 행동 결과 "*':)' –

+0

@ DavidC.Rankin : 예, 일부 또는 모든 컴파일러/시스템에서 증상을 일으키므로 "작동한다"는 것이 코드가 정확하다고 말하는 것만으로는 충분하지 않습니다. – ShadowRanger

+0

예, 당신이 말한 요점을 이해했습니다. 금요일 밤에 좀 이상하거나 유머러스하게 들렸습니다. (따라서':)' –