4

在此处发布我的代码片段。我试图在调试中站稳脚跟。

struct dirent *s_dirent;
char path[300];
....
bzero(path,300);
...
fd_dir = opendir(path);
while((s_dirent = readdir(fd_dir))!=NULL)
{
     if(s_dirent->d_name[0] == '.')
          continue;
     else
          break;
 }
if(s_dirent == NULL)
{
   if(closedir(fd_dir)!=0)
       perror("Error on closedir");
 }
else
{

  if(closedir(fd_dir)!=0)/*Line number 249*/
      perror("Error on closedir");

  /*some comments*/
  strcat(path,"/");
  strcat(path,s_dirent->d_name);/*Line number 254*/
 }

Valgrind 输出:

==3287== Invalid read of size 1
==3287==    at 0x40069E0: strcat (mc_replace_strmem.c:176)
==3287==    by 0x804D6B4: online_bck (backup_manager.c:254)
==3287==    by 0x8049F96: on_bck_beg (TxFS_manager.c:181)
==3287==    by 0x8049818: handler (Reader.c:236)
==3287==    by 0xBF5F18: start_thread (in /lib/libpthread-2.12.90.so)
==3287==    by 0xB37A2D: clone (in /lib/libc-2.12.90.so)
==3287==  Address 0x402a39b is 35 bytes inside a block of size 32,792 free'd
==3287==    at 0x40057F6: free (vg_replace_malloc.c:325)
==3287==    by 0xAF6C67: closedir (in /lib/libc-2.12.90.so)
==3287==    by 0x804D65A: online_bck (backup_manager.c:249)
==3287==    by 0x8049F96: on_bck_beg (TxFS_manager.c:181)
==3287==    by 0x8049818: handler (Reader.c:236)
==3287==    by 0xBF5F18: start_thread (in /lib/libpthread-2.12.90.so)
==3287==    by 0xB37A2D: clone (in /lib/libc-2.12.90.so)

任何帮助将不胜感激。谢谢

4

3 回答 3

5

您不应访问readdir()调用 a 后返回的数据closedir()。这是因为closedir()可以释放在 opendir/readdir 中分配的任何资源(例如内存)。

如果要保存 dirent* 结构,可以切换到readdir_rreaddir 的变体(使用不同的参数集)。

更新: Valgrind 输出的解码:

        V - note single space here; it is beginning of error message. 
==3287== Invalid read of size 1
==3287==    at 0x40069E0: strcat (mc_replace_strmem.c:176)

 backtrace skipped

Valgrind 说错误是Reading of invalid data, sized 1 byte,这不是内存泄漏。这是不正确的内存访问。而这个读取的参与者是strcat()(被跳过的回溯调用)。为什么数据无效?有子消息

        VV - note two spaces here, it is continuation of error message
==3287==  Address 0x402a39b is 35 bytes inside a block of size 32,792 free'd
==3287==    at 0x40057F6: free (vg_replace_malloc.c:325)
==3287==    by 0xAF6C67: closedir (in /lib/libc-2.12.90.so)

该字节无效(不允许从中读取),因为它是已释放的内存段的一部分(您无法从刚刚释放的内存中读取)。这是谁做的?看回溯:closedir是free的调用者。

于 2011-08-06T02:28:43.793 回答
0

s_dirent == NULL,检查while循环退出条件。

于 2011-08-06T02:13:34.790 回答
0

当您到达 时strcat(),您已经退出了 while 循环。while 循环退出一次s_dirent为 NULL。

但只要s_direct是 NULL,你运行这个:

strcat(path,"/");
strcat(path,s_dirent->d_name);/*Line number 254*/

...它试图取消引用 s_dirent。因此,valgrind 然后告诉您检查从 backup_manager.c:254 调用的 strcat() 调用:

==3287== Invalid read of size 1
==3287==    at 0x40069E0: strcat (mc_replace_strmem.c:176)
==3287==    by 0x804D6B4: online_bck (backup_manager.c:254)

我猜你只有在处理一个包含“.”、“..”条目的空目录或只包含以“.”开头的隐藏文件的目录时才会遇到这个问题?

于 2011-08-06T02:20:51.290 回答