C - 指数函数导致文件 IO 出现段错误
编辑:为了回答一些问题,这是经过修订的但仍然无法工作的代码(其中大部分是从一开始就存在的,但我应该明确表示我初始化了文件指针等)。同样,只有在 exp() 之前添加写入或完全删除 exp() 才有效:
FILE *outfile;
char *outfilename;
outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
strcpy(outfilename, "outfile.txt");
outfile = fopen(realoutfilename, "w");
/* If this is uncommented, there isn't a segfault
if(realoutfile!=NULL && imoutfile!=NULL){
fprintf(outfile, "\r\n");
fseek(outfile,0,SEEK_SET);
}
*/
gauss = (double*) calloc(points, sizeof(double));
/* Maths and stuff */
if(outfile!=NULL){
for(i=0;i<points;i++){
/* this prints fine */
printf(outfile, "%g,\r\n", gauss[i]);
/* Seg fault is here */
fprintf(outfile, "%g,\r\n", gauss[i]);
}
}
fclose(outfile);
free(outfile);
并且我正在编译:
gcc main.c -lm -Wall -Wextra -Werror -Wshadow -g -o main
To澄清一下,它没有到达函数的末尾 - 所以它不是在释放时崩溃的。崩溃是当它尝试在 for 循环中写入文件时发生的。
我已经检查过 exp() 没有溢出或下溢,正如我所说,我可以 printf 输出,但文件写入是不行的。如果我尝试一个简单的调用,例如 exp(2),它也会失败。
gdb 回溯是(我对 gdb 不太熟悉,认为它可能有帮助):
#0 0xff15665c in _malloc_unlocked () from /lib/libc.so.1
#1 0xff15641c in malloc () from /lib/libc.so.1
#2 0xff1a8c80 in _findbuf () from /lib/libc.so.1
#3 0xff1a8f0c in _wrtchk () from /lib/libc.so.1
#4 0xff1ad834 in _fwrite_unlocked () from /lib/libc.so.1
#5 0xff1ad798 in fwrite () from /lib/libc.so.1
#6 0x000128ac in gaussian ()
#7 0x00010f78 in main ()
任何帮助将不胜感激!
EDIT: To answer some questions, this is the revised and still not working code (most of it was there to begin with, but I should have been explicit that I initialised the file pointer, etc). Again, only works if I either add a write before the exp() or remove the exp() entirely:
FILE *outfile;
char *outfilename;
outfilename = (char *)malloc(FILENAME_MAX*sizeof(char));
strcpy(outfilename, "outfile.txt");
outfile = fopen(realoutfilename, "w");
/* If this is uncommented, there isn't a segfault
if(realoutfile!=NULL && imoutfile!=NULL){
fprintf(outfile, "\r\n");
fseek(outfile,0,SEEK_SET);
}
*/
gauss = (double*) calloc(points, sizeof(double));
/* Maths and stuff */
if(outfile!=NULL){
for(i=0;i<points;i++){
/* this prints fine */
printf(outfile, "%g,\r\n", gauss[i]);
/* Seg fault is here */
fprintf(outfile, "%g,\r\n", gauss[i]);
}
}
fclose(outfile);
free(outfile);
And I'm compiling with:
gcc main.c -lm -Wall -Wextra -Werror -Wshadow -g -o main
To clarify, it doesn't reach the end of the function - so it's not the freeing that it crashes on. The crash is when it tries to write to the file in that for loop.
I've checked that exp() isn't over or underflowing, as I say, I can printf the output, but file writing is a no-no. It also fails if I try a simple call, say exp(2).
The gdb backtrace is (I'm not that familiar with gdb, thought it might help):
#0 0xff15665c in _malloc_unlocked () from /lib/libc.so.1
#1 0xff15641c in malloc () from /lib/libc.so.1
#2 0xff1a8c80 in _findbuf () from /lib/libc.so.1
#3 0xff1a8f0c in _wrtchk () from /lib/libc.so.1
#4 0xff1ad834 in _fwrite_unlocked () from /lib/libc.so.1
#5 0xff1ad798 in fwrite () from /lib/libc.so.1
#6 0x000128ac in gaussian ()
#7 0x00010f78 in main ()
Any help would be greatly appreciated!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题就在这里:
你不能像这样分配一个字符串,你必须使用
strcpy
:发生的情况是你正在用字符串赋值。然后你尝试释放它
free(outfilename);
。由于您正在释放字符串文字,因此行为未定义,因此会发生崩溃。至于为什么它在一种情况下崩溃而不是另一种情况。该行为是未定义的,因此任何事情都可以发生。您的指数函数代码可能会对堆栈/堆执行某些操作,从而导致其崩溃/不崩溃。
编辑:我希望这只是一个拼写错误或错误复制,但我也没有看到
outfile
是在哪里初始化的。如果它确实从未初始化过,那么这就是另一个错误。 (很可能是导致您的特定段错误的原因)所以它应该如下所示:
The problem, is here:
You can't assign a string like that, you have to use
strcpy
:What's happening is that you're are overwriting the
outfilename
pointer with the string assignment. Then you try to free itfree(outfilename);
. Since you are freeing a string literal, the behavior is undefined, hence the crash you are getting.As for why it crashes in one case and not the other. The behavior is undefined, therefore anything is allowed to happen. It's possible that your exponential function code does something to the stack/heap that could be causing it crash/not crash.
EDIT : I hope it's just a typo or mis-copy, but I also don't see where
outfile
is initialized. If it really is never initialized, then that's the other error. (and most likely the one that's causing your particular segfault)So it should look like this:
首先,您确实应该在启用所有警告并生成调试信息的情况下进行编译;与
gcc
一起表示-Wall -g
标志。您应该使用
strdup
并且我没有看到对fopen
的调用,例如您应该学习使用调试器
gdb
(或者可能是它的ddd
图形前端)。First, you really should compile with all warnings enabled and with debugging information produced; with
gcc
that means the-Wall -g
flags.You should use
strdup
and I see no call tofopen
egAnd you should learn to use the debugger
gdb
(or perhaps itsddd
graphical front-end).您只能释放从
malloc
返回的内容。您不能将free
指针传递给常量!You can only free something you got back from
malloc
. You can't passfree
a pointer to a constant!