使用C中的fgets逐行读取文件,读取大小无效

使用C中的fgets逐行读取文件,读取大小无效,c,valgrind,C,Valgrind,我的代码中不断出现valgrind错误,三个小时后我仍然不知所措,所以我需要你们的帮助 所以我基本上只是读取目录中包含的文件并对其进行解析,所以我复制了代码中仍然产生错误的最短示例: int main(int argc, char** argv) { parse_files_dir("/Users/link_to_dir_example/"); return (EXIT_SUCCESS); } void parse_files_dir(char *dirLink){ int dLink

我的代码中不断出现valgrind错误,三个小时后我仍然不知所措,所以我需要你们的帮助

所以我基本上只是读取目录中包含的文件并对其进行解析,所以我复制了代码中仍然产生错误的最短示例:

int main(int argc, char** argv) {

 parse_files_dir("/Users/link_to_dir_example/");
 return (EXIT_SUCCESS);
}

void parse_files_dir(char *dirLink){

int dLink_l =strlen(dirLink);
int max_len = dLink_l*2;

char* full_path=malloc(sizeof(char)*(max_len+1));
//check if null pointer...

strncpy(full_path, dirLink, dLink_l);

DIR *dir;
struct dirent *dir_con;
dir=opendir(dirLink);

if (dir == NULL){
    fprintf(stderr, "Problem opening directory: \"%s\". Aborting...\n", dirLink);
    exit(EXIT_FAILURE);
}

while((dir_con = readdir(dir)) != NULL){

    if (dir_con->d_name[0] == '.') continue;

    if (dLink_l+strlen(dir_con->d_name)>max_len) //realloc full path..

    strncpy(&full_path[dLink_l], dir_con->d_name, strlen(dir_con->d_name));
    full_path[dLink_l+strlen(dir_con->d_name)] = '\0';        

    parse_one_file(full_path);  // (*) <=== valgrind complain 
    full_path[dLink_l] = '\0';
} 
free(full_path);
closedir(dir);
}
 ==4929== Invalid read of size 32
 ==4929==    at 0x1003DDC1D: _platform_memchr$VARIANT$Haswell (in       /usr/lib/system/libsystem_platform.dylib)
 ==4929==    by 0x1001CF66A: fgets (in /usr/lib/system/libsystem_c.dylib)
 ==4929==    by 0x100000CD8: parse_one_file (main.c:93)
 ==4929==    by 0x100000B74: parse_files_dir (main.c:67)
 ==4929==    by 0x100000944: main (main.c:28)
 ==4929==  Address 0x100804dc0 is 32 bytes before a block of size 4,096 in arena "client"
所以我真的不知道我的错误在哪里,我一直清空缓冲行,我从来没有读过比分配的字节更多的字节

有趣的是,我注意到,如果目录“dirLink”只有一个文件,则不会发生错误,但是如果我有两个或更多文件,则会发生错误,因此我认为错误在于如何生成路径“full_path”,但随后我将行“*”替换为(仅出于测试原因)

错误依然存在

if(line[line_len-1] == '\n'){
  strncpy(&line_full[line_full_len], line, line_len);
  line_full_len+=line_len;
}
这是不完全正确的,您只能
strncpy()(line\u max-line\u full\u len)
字节,不能保证您可以复制
line\u len
字节。或者换句话说。从位置行_full[500]开始,不能再写入1000字节


else分支中也存在相同的错误。

除非文件的总字节数小于1000字节,否则您将在行尾写入完整的缓冲区,该缓冲区的总大小仅为1000字节。这将不可避免地破坏您的内存,并导致伪错误,就像您在fgets中遇到的错误一样。

您最近如何
//检查行满时是否有足够的内存剩余
dLink\u l
的计算应为:
int dLink\u l=strlen(dirLink)+1
其中“+1”将在字符串末尾包含NUL字节。在对malloc()的调用中,表达式:
sizeof(char)
被定义为1。该表达式绝对不会影响传递给malloc()的参数,并会使代码混乱。建议删除该表达式。始终检查malloc()返回的值(!=NULL),以确保在系统函数调用失败时操作成功,然后立即(以后不是几行代码)调用
peror()
,以显示错误消息和系统错误消息,如
errno
所选,将输出到stderr返回此类行:
if(file==NULL)//error message
在输出错误消息的同时,也调用return或exit(),因为文件未打开,因此无法从中读取。我知道,我只是通过写入“//检查行\u full是否有足够的内存剩余”来省略该部分
   parse_one_file("another/example/path/");
if(line[line_len-1] == '\n'){
  strncpy(&line_full[line_full_len], line, line_len);
  line_full_len+=line_len;
}