【问题标题】:Fclose causing seg fault in C [closed]Fclose导致C中的段错误[关闭]
【发布时间】:2013-02-18 16:59:50
【问题描述】:

当且仅当我尝试关闭文件时,我才会不断收到段错误:

   FILE *outFilePtr = fopen(*(argv + 2), "w"); //open file, yes i'm sure it opens


   fclose(outFilePtr); //sometime later in the program.

程序在没有 flcose() 的情况下从头到尾运行。有什么建议吗?

gdb 上的错误重定向到这里:假设它是一个声明了所有变量的函数。 gdb 也责怪我什至没有使用的 strtol 。

 int t;
     char line[50];

          for (t = 0; t < lines; t++){
              fgets(line, 50, filePtr);
             strcpy(*string[t], strtok(line, " "));
              *(num1 + t) = atoi(strtok(NULL, " "));
              *(num2 + t) = atoi(strtok(NULL, " "));
           }

内存分配函数

 void dynamicArray(int** num1, int** num2, char*** str, int size)
 { 
     int i = 0;

*(num1) = (int*)malloc(sizeof(int) * size);
*(num2) = (int*)malloc(sizeof(int) * size);

*(str) = (char**)malloc(sizeof(char*) * size);

for( i = 0; i < size; i++){
    *(*(str) + i) = (char*)malloc(sizeof(char) *size);
}

return;
 }

【问题讨论】:

  • 您遗漏了中间发生的有趣部分。从您所展示的内容来看,不,它不应该崩溃。
  • 你能给出 MWE(最小工作示例)吗?
  • 这里有点跑题了:为什么所有这些都是*(blah + x) 而不是blah[x]
  • 需要更多代码。您可以继续将代码精简为 MWE 吗?这种黑盒模型方法无法帮助我们帮助您。
  • 别说了,太烦人了。显式 * 表示有经验的 C 代码阅读器正在发生一些“特殊”的事情。所以它需要“特别”注意。一个普通的数组下标,虽然在技术上是相同的,但完全显而易见,不会引发“特别”注意。希望我的解释不要太奇怪。

标签: c fault fclose


【解决方案1】:

为了确定,检查outFilePtr 不为空:

if (outFilePtr) {fclose(outFilePtr); outFilePtr = NULL;}

我总是在关闭文件时这样做,并且我还将指针指向 NULL 以避免尝试关闭同一个文件两次(这也可能导致麻烦)。

但最有可能的原因是某些内存泄漏或未定义的行为导致混乱,而 segfault 只是由 fclose() 触发。

【讨论】:

  • 那么为什么 fclose() 会触发它。错误代码指向atoi的错误,但数组都正确填充..我不明白。
  • fclose() 上,标准库向操作系统释放资源。我可以想象,如果此时出现问题,您最终可能会在只读内存上写入或触发其他异常(对我来说,div 为零似乎不太可能,但仍有可能)。
  • 所以很可能,我在某个地方有一些不应该在的地方,并且程序直到我尝试关闭这个文件才意识到这一点?
  • 正是如此。 Valgrind 或周围的一些assert() 可能会帮助您找到正确的位置。
【解决方案2】:

我的猜测是当你到达 fclose() 时 outFilePtr 的值没有被保留。

您的代码 sn-p 太短,并且错过了太多其他可能很重要的东西...... 什么是字符串和num2;他们分配了多大;等等……

此外,*(num2 + t) 的第一个存储被第二个 *(num2 + t) 覆盖。

另外,还可以看看 ARRAYS.... num2[t] 比 *(num2+t) 更容易阅读,并且做同样的工作。

【讨论】:

  • 覆盖部分不适用,是传输代码时出错。我不能给整个程序很长的时间..它怎么会不被保留?为什么它会直接指向这里?
  • 不被保留的最简单方法是因为它已被覆盖——因此我对所有分配进行了查询。尝试在 fopen 之后和 fclose 之前添加 printf ("%X\n", (unsigned)outFilePtr); - 确保值相同。另一个想法 - 你不会不止一次关闭是吗?
【解决方案3】:

除了你可怕的数组访问语法。您忘记复制输入字符串行。 strtok 总是指向同一个缓冲区,每行都会改变。

 int t;
 char line[50];

      for (t = 0; t < lines; t++){
          fgets(line, 50, filePtr);
          strings[t] = strdup(strtok(line, " ")));
          num1[t]    = atoi(strtok(NULL, " "));
          num2[t]    = atoi(strtok(NULL, " "));
       }

在你的分配代码中,你也只分配了 5 个字节而不是 50 个。如果你真的只分配了 5 个字节,那么你破坏了堆,这通常表现为崩溃 fclose

void dynamicArray(int** num1, int** num2, char*** str, int size)
{ 
int i = 0;

*num1 = malloc(sizeof(int) * size);
*num2 = malloc(sizeof(int) * size);

*str = malloc(sizeof(char*) * size);

for( i = 0; i < size; i++)
  (*str)[i] = malloc(50);      /* sizeof (char) is by definition 1 */

return;
}

【讨论】:

  • 我不知道那五个人是怎么到那里的。我的代码中没有这些错误,我深表歉意。我的真实代码中有 strcpy()。
  • 好的。它要么是固定大小的分配,要么是 strcpystrdup,但在 dynamicArray() 中没有特定的分配循环。
  • 但正如我所说,在我的回复中。您的问题看起来像是某处的堆覆盖,或双重释放。
猜你喜欢
  • 2014-04-25
  • 2011-10-18
  • 1970-01-01
  • 1970-01-01
  • 2021-06-11
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
相关资源
最近更新 更多