重复使用strdup导致内存泄漏

3

我正在创建一个由linux_dirent结构(d)获得的文件名数组。 在循环的每次迭代中,使用以下方法获得一个文件名:

d_entry = strdup(d->d_name);

然后将指向此对象的指针添加到数组中:

srcList[aSz] = d_entry;

由于指针数组需要指向有效内存,因此我不能这样做:

d_entry = strdup(d->d_name);
srcList[aSz] = d_entry;
free(d_entry);

在使用完数组后,仅使用free(d_entry)只会释放为最后一个d_entry分配的strdup/malloc的内存。

Valgrind确认了内存泄漏。

有没有方法来解决这个问题,或者我应该考虑使用memcpy将文件名移动到单独的缓冲区,然后再创建指向数组中的指针。

核心循环:

   for (bpos = 0; bpos < nread;) {
       d = (struct linux_dirent *) (buf + bpos);
       d_type = *(buf + bpos + d->d_reclen - 1);
       if( d->d_ino != 0 && d_type == DT_REG || d_type == DT_UNKNOWN ) {

           /* get directory entry */
            d_entry = strdup(d->d_name); // << repeat allocations here

           /* save pointer to filename in array 'srcList' */
                srcList[aSz] = d_entry;
                aSz++;
       }
       if ( aSz == DAY_COUNT +1 ) break;
       bpos += d->d_reclen;
   }

1
当您不再需要srcList[]中的条目时,请确保使用free()释放它们。 - EOF
1
为什么不稍后迭代您的数组并释放所有内容呢? - nneonneo
1
你需要为每次调用 strdup 调用一次 free,迟早要这样做。 - M.M
3
@anita2R,“指针”在你的“srcList”中。 - nneonneo
1
那么?将这些小家伙NULL掉。 - Martin James
显示剩余6条评论
1个回答

1
如评论中所讨论的,泄漏问题已得到修复。
for ( i=0; i< size;i++)
   free( srcList[i] );

当数组不再需要时

这样做是可行的,但由于数组中的某些元素未被填充,我使用了 if(srcList[n]) free(srcList[n]);。该数组被初始化为 nulls,因此只有填充的元素才会被用于释放。 - anita2R
@anita2R 我晚了四年,但如果实现遵循ISO,free()在NULL上调用是安全的。https://en.cppreference.com/w/c/memory/free - Hunter Kohler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接