1

发生错误后,我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

更新2:

看起来与recv()函数中传递的缓冲区大小有关系。如果BUFSIZE1,给出上述错误。但是如果BUFSIZE是例如,128 没有错误。有人可以解释这种行为吗?

4

2 回答 2

2

不可能从这个片段中确切地知道什么是错误的。但总的来说,“为什么我在调用 [rock solid c library func here] 时会出现段错误”这个问题的答案?通常是:你的堆栈是油炸的。阅读,当然是一个主要的嫌疑人。

于 2012-10-27T18:22:33.900 回答
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 位但是int32 位。因此,取决于编译器如何安排内存空间,有时指针将适合 32 位,有时它们不会,有时不正确的地址恰好匹配其他分配的内存页面(未定义/空白输出),有时它们不匹配(分段过错)。我碰巧遇到了一种情况,它不适合 32 位,编译器将返回值“强制转换”为 32 位int然后将它(for printf)转换回 64 位char*(没有丢失的 64 位的上半部分现在为零),当处理器尝试从未分配的内存页面读取时,会出现未定义的行为。

诊断您的特定情况将需要一个简短的、自包含的、可编译的示例 (SSCCE),例如您引用了一个recv函数调用(我假设您的意思是阅读?)。

您还需要包含用于编译代码的命令,例如,链接命令的顺序可能会显着改变生成代码的行为。

于 2020-02-16T21:21:38.903 回答