2017-10-14 133 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

是的,我明白了你所说的症结所在,在这个星期五的晚上,这让我觉得有点奇怪/幽默(因此':''' –