分段错误:核心转储
Posted
技术标签:
【中文标题】分段错误:核心转储【英文标题】:Segmentation Fault: Core Dumped 【发布时间】:2016-10-19 07:44:37 【问题描述】:#include <stdio.h>
int main()
FILE *fp = ("Hello.txt","w");
fprintf (fp, "\n Hello World");
fclose(fp);
return 0;
我在运行此程序时收到此消息
“分段错误(核心转储)”。
如果我知道为什么会发生这种情况以及如何解决它,那将非常有帮助。我目前正在使用 ubuntu 中的代码块。在此先感谢:)
【问题讨论】:
FILE *fp = ("Hello.txt","w");
-> FILE *fp = fopen("Hello.txt","w");
你的编译器至少没有显示警告吗?
在使用 fprintf() 函数之前,有没有检查文件是否创建成功 ==> fp != NULL ?
是的,错过了:-)
@J.Piquard,鉴于他的代码状态,该检查实际上会通过。
【参考方案1】:
是的。正如迈克尔沃尔兹评论的那样。你错过了fopen
#include <stdio.h>
int main()
FILE *fp = fopen("Hello.txt","w");
fprintf (fp, "\n Hello World");
fclose(fp);
return 0;
【讨论】:
【参考方案2】:您的代码中缺少 fopen。 此外,为避免其他问题,请始终检查 fopen 的返回值。如果打开文件出现任何问题(例如空间不足、权限错误),它将为 NULL
#include <stdio.h>
int main(int argc, char **argv)
FILE *fp = fopen("Hello.txt", "w");
if (fp==NULL)
return -1;
fprintf (fp, "\n Hello World");
fclose(fp);
return 0;
【讨论】:
【参考方案3】:行:
FILE *fp = ("Hello.txt","w");
从意图的角度来看显然是错误的,因为您似乎错过了告诉编译器您要调用的实际函数的步骤。你几乎肯定想做的是:
FILE *fp = fopen("Hello.txt", "w");
任何体面的编译器都应该警告您这一点,例如 gcc
警告:
FILE *fp = ("Hello.txt","w");
^
warning: initialization from incompatible pointer type
而且我经常使用-Werror
标志进行编译,以便让编译器将警告视为错误,从而准确捕获此类事情。
您实际上可能想知道为什么编译器认为这只是一个警告,但事实是它是完全有效的代码。表达式周围的括号是有效的,这就是为什么你可以写成 x = 7
或 x = (7)
,甚至是 x = (((((7)))))
,并且它们的意思是一样的。
剩下的只是括号内的表达式,这使用了C逗号运算符。基本上,表达式 a, b
计算 a
(丢弃结果)然后计算 b
并将其用作表达式的结果。
您可以使用以下程序验证此行为,该程序输出w
:
#include <stdio.h>
int main (void)
char *fp = ("Hello.txt", "w");
puts (fp);
return 0;
你可能认为你对这种野兽的使用有限,但我保证你使用它的次数比你想象的要多得多,例如:
for (i = 0, j = 0; i < 100; i++, j += 2)
printf ("%d x 2 = %d\n", i, j);
在这种情况下,丢弃子表达式的结果很好,因为您只是依赖于评估的 ++
副作用。
在你的情况下,声明:
FILE *fp = ("Hello.txt","w");
将评估"Hello.txt"
并使用"w"
分配给fp
(因此出现不兼容的指针警告)。
然后,当您尝试使用"w"
的地址,就好像它是一个有效的FILE
指针一样,所有的赌注都被取消了。
并且,作为旁注,您通常应该检查所有可能失败的函数的返回值,如果此类失败以后可能会影响您的程序。假设fopen
(或malloc
,或许多其他函数)将始终有效是不明智的。对于fopen
,需要确保返回的值不是NULL
。
【讨论】:
以上是关于分段错误:核心转储的主要内容,如果未能解决你的问题,请参考以下文章