Readdir / closedir – Valgrind显示“无效读取”

在这里发布我的代码片段。 我正在试图find一个基础debugging。

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) 

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

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

如果你想保存dirent * struct,你可以切换到readdir的readdir_r变体(使用不同的参数)。

更新: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) 

该字节是无效的(不允许被读取),因为它是free-d的内存段的一部分(你不能从刚刚释放的内存中读取-d)。 这是谁? 回顾一下: closedir是免费的来电者。

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

当你到达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调用strcat()的调用:254:

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

我猜你只是在处理包含“。”,“..”或仅包含以“。”开头的隐藏文件的目录的空目录时才打这个文件?