发生错误后,我自然会拨打perror()
。但是当我这样做时,我遇到了分段错误或printf("error: %s\n", strerror(errno));
我不知道是什么在讨价还价。
int fd;
if((fd = open(FILENAME, O_RDONLY)) == -1) {
perror("fbi");
exit(1);
}
for(;;) {
readed = read(fd, buffer, BUFSIZE);
if(readed == 0)
break;
if(readed == -1) {
perror("fbi"); // <- here's the error
exit(1);
}
如何解决这个问题?
更新
printf("%d\n", errno); // given 9
UPDATE2:
看起来与recv()
函数中传递的缓冲区大小存在关系。如果BUFSIZE
为1
,请提供上述错误。但如果BUFSIZE
为128
,则{{1}} 无错误。有人可以解释这种行为吗?
答案 0 :(得分:2)
无法确切地知道此代码段的错误。但总的来说,回答“为什么我在调用[rock solid c library func here]时会出现段错误?”通常是:你的筹码是炒的。阅读,当然是一个主要的嫌疑人。
答案 1 :(得分:1)
确定要使用#include <string.h>
等。
我在宏中使用#include <errno.h>[...]printf("%s\n",strerror(errno));[...]
几天都没有问题。然后,有一天,我向strerror(errno)
添加了另一个调用,结果包括异常行为,分段错误,错误的返回类型,意外的程序终止(退出状态为0),所有这些都取决于我如何调用第二个strerror
打电话。
像strerror(errno)==NULL
这样简单的事情将导致warning: comparison between pointer and integer
。
原来是因为我使用了strerror
而没有#include <string.h>
的原因。由于函数 是作为标准c库的一部分正确链接的,因此编译器会为函数创建一个(标准规定的)“隐式声明”,该隐式声明采用int strerror(int)
的定义。不兼容的返回类型会引起问题,因为在我的系统上char*
是64位,而int
是32位。因此,取决于编译器如何安排内存空间,有时指针可以容纳32位,有时则不可以,有时不正确的地址恰好与其他分配的内存页匹配(未定义/空白输出),有时不匹配(分段故障)。我碰巧遇到了这样一种情况,它不能容纳32位,并且编译器将返回值“强制转换”为32位int
,然后将其返回(对于printf
)为64 char*
位(没有丢失的64位的上半部分现在为零),并且在处理器尝试从未分配的内存页读取时出现未定义的行为。
诊断您的特殊情况将需要一个short, self contained, compilable, example (SSCCE),例如,您引用了一个recv
函数调用(我假设您是读过吗?)。
您还需要包括用于编译代码的命令,例如,链接命令的顺序可能会显着改变生成的代码的行为。