如何使用valgrind修复C中的错误:大小为8的无效写入

huangapple go评论86阅读模式
英文:

How can I fix this error in C using valgrind: invalid write of size 8

问题

After compiling my code, I've got some issues regarding the memory. After doing ./valgrind on my Linux terminal, I've got the following error for this function:

  1. > invalid write of size 8 at read_lines_from_file.

Here is my function read_lines_from_file:

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <math.h>
  6. int lines_count = 0;
  7. char** read_lines_from_file(FILE* file) {
  8. fseek(file, 0, SEEK_SET);
  9. char** lines = NULL;
  10. char line[100];
  11. while (fgets(line, 100, file)) {
  12. line[strlen(line) - 1] = '
    #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <math.h>
  17. int lines_count = 0;
  18. char** read_lines_from_file(FILE* file) {
  19.     fseek(file, 0, SEEK_SET);
  20.     char** lines = NULL;
  21.     char  line[100];
  22.     while (fgets(line, 100, file)) {
  23.         line[strlen(line) - 1] = '\0';
  24.         lines = realloc(lines, (lines_count + 1) * sizeof(char*));
  25.         lines[lines_count] = malloc(strlen(line) + 1);
  26.         strcpy(lines[lines_count], line);
  27.         lines_count++;
  28.     }
  29.     return lines;
  30. }
  31. ';
  32. lines = realloc(lines, (lines_count + 1) * sizeof(char*));
  33. lines[lines_count] = malloc(strlen(line) + 1);
  34. strcpy(lines[lines_count], line);
  35. lines_count++;
  36. }
  37. return lines;
  38. }

I don't understand where it comes from and how I can correct that to remove this error.

英文:

After compiling my code, I've got some issues regarding the memory. After doing ./valgrind on my Linux terminal, I've got the following error for this function:

> invalid write of size 8 at read_lines_from_file.

Here is my function read_lines_from_file:

  1. #include &lt;stdio.h&gt;
  2. #include &lt;stdlib.h&gt;
  3. #include &lt;string.h&gt;
  4. #include &lt;ctype.h&gt;
  5. #include &lt;math.h&gt;
  6. int lines_count = 0;
  7. char** read_lines_from_file(FILE* file) {
  8. fseek(file, 0, SEEK_SET);
  9. char** lines = NULL;// &#231;a renvoie NULL si le fichier est vide
  10. char line[100];
  11. while (fgets(line, 100, file)) {// nous faisons l&#39;hypoth&#232;se qu&#39;une ligne ne d&#233;passe pas 100 caract&#232;res
  12. line[strlen(line)-1]=&#39;
    #include &lt;stdio.h&gt;
  13. #include &lt;stdlib.h&gt;
  14. #include &lt;string.h&gt;
  15. #include &lt;ctype.h&gt;
  16. #include &lt;math.h&gt;
  17. int lines_count = 0;
  18. char** read_lines_from_file(FILE* file) {
  19. fseek(file, 0, SEEK_SET);
  20. char** lines = NULL;// &#231;a renvoie NULL si le fichier est vide
  21. char  line[100];
  22. while (fgets(line, 100, file)) {// nous faisons l&#39;hypoth&#232;se qu&#39;une ligne ne d&#233;passe pas 100 caract&#232;res
  23. line[strlen(line)-1]=&#39;\0&#39;;// on enl&#232;ve le \n
  24. lines = realloc(lines, (lines_count + 1) * sizeof(char*));
  25. lines[lines_count] = malloc(strlen(line) + 1);
  26. strcpy(lines[lines_count], line);
  27. lines_count++;
  28. }
  29. return lines;
  30. }
  31. &#39;;// on enl&#232;ve le \n
  32. lines = realloc(lines, (lines_count + 1) * sizeof(char*));
  33. lines[lines_count] = malloc(strlen(line) + 1);
  34. strcpy(lines[lines_count], line);
  35. lines_count++;
  36. }
  37. return lines;
  38. }

I don't understand where it comes from and how I can correct that to remove this error.

答案1

得分: 2

存在以下问题:

  • 不清楚是否解决了"在split处写入大小为1的无效写入"的问题。
  • 调用者缺乏关于读取了多少行的信息。
  • 在第2次调用read_lines_from_file时未重置为0,因此向调用者传递了错误的行数。
  • 存在潜在的黑客攻击漏洞:当第一个字符是空字符时,line[strlen(line)-1]='\0'; 会导致未定义行为。而且,输入未必包括 '\n'
  • 缺乏错误检查:代码未检查分配错误。
  • 无法很好处理长度超过100个字符的行。
英文:

Code has at least these problems:

Unclear if any solve "invalid write of size 1 at split".

Caller lacks info as to how many lines were read

read_lines_from_file, on the 2nd call is not reset to 0 and so conveys to the caller the wrong number of lines.

Hacker exploit

line[strlen(line)-1]=&#39;\0&#39;; is UB where the first character read is a null character.

Also, input does not certainly include a &#39;\n&#39;.

  1. // Better as
  2. line[strcspn(line, &quot;\n&quot;)] = &#39;
     // Better as
  3. line[strcspn(line, &quot;\n&quot;)] = &#39;\0&#39;;
  4. &#39;;

Lack of error checking

Code does not check for allocation errors.

Lines of 100+ characters are not well handled

huangapple
  • 本文由 发表于 2023年2月8日 20:57:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/75386142.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定