0

一般来说,我对 C 和内存分配都很陌生。基本上我要做的是复制未知大小的输入文件的内容并使用递归反转它的内容。我觉得我很接近,但是当我尝试输入我认为是文件的反转内容的内容时,我一直遇到分段错误(我认为是因为我认为我做对了...... )

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int recursive_back(char **lines, int lineNumber, FILE *input) {

   char *input_line = malloc(sizeof(char) * 1000);
   lines = realloc(lines, (lineNumber) * 1000 * sizeof(char));
   if(fgets(input_line, 201, input) == NULL) {
      *(lines + lineNumber) = input_line;
      return 1;
   }  
   else {
      printf("%d\n", lineNumber);
      return  (1+recursive_back(lines, ++lineNumber, input));

   }

}

void backward (FILE *input, FILE *output, int debugflag )   {
   int i;
   char **lines;                            //store lines in here
   lines = malloc(1000 * sizeof(char *) ); //1000 lines

   if(lines == NULL) {         //if malloc failed
      fprintf(stderr, "malloc of lines failed\n");
      exit(1);
   }

   int finalLineCount, lineCount;
   finalLineCount = recursive_back(lines, 0, input);

   printf("test %d\n", finalLineCount);

   for(i = finalLineCount; i > 0; i--) {     
      fputs(*(lines+i), output);            //segfault here
   }

}

我正在使用一个简单的输入文件来测试代码。我的输入文件有 6 行长,上面写着“这是一个测试输入文件”。实际输入文件正在另一个函数中打开并传递给后向函数。我已经验证了我的程序中的其他功能可以正常工作,因为我一直在使用不同的选项。这两个功能是我唯一遇到问题的功能。我究竟做错了什么?

4

1 回答 1

0

你的问题在这里:

lines = realloc(lines, (lineNumber) * 1000 * sizeof(char));

正如@ooga 所说。它至少有三个不同的问题:

  1. recursive_back()您正在重新分配的局部变量 指向的内存块lines,并将新地址(假设重新分配成功)存储回该局部变量。新位置不一定与旧位置相同,但指向它的唯一指针是一个局部变量,该变量在recursive_back(). 调用者对应的变量没有改变(包括调用者recursive_back()自己的时候),因此不能再依赖recursive_back()返回后是一个有效的指针。

  2. 您使用错误的类型分配空间。 lines具有 type char **,因此它指向的对象具有 type char *,但是您正在根据大小保留空间char

  3. 您没有保留足够的空间,至少在第一次调用时,当lineNumber为零时。在该调用中,当请求的空间正好为零字节时, 的效果realloc()释放指向的内存lines。在随后的调用中,分配的空间总是比您认为分配的少一行。

realloc()如果您可以依赖输入最多有 1000 行,那么看起来完全没有必要,因此您应该考虑将其删除。如果您确实需要能够以调用者将看到的方式重新分配,则调用者需要将指针传递给其变量,以便recursive_back()可以通过该指针对其进行修改。

于 2015-07-01T02:48:49.657 回答