C- getline返回-1,eof未设置,当给出非常大的输入时未设置errno



我认为这三个条件不能同时发生。我有:

char* line = NULL;
size_t capacity = 0;
ssize_t n = getline(&line, &capacity, stdin);
if (n == -1) {
    int err = errno; // preserve it
    if (feof(stdin) == 0) { // means not EOF
        printf(strerror(err)); // "Success"
    }
}

getline文档要求

两个功能在未能读取线路(包括文件终止条件)时返回-1。如果发生错误,则将ERRNO设置为指示原因。

所以我有一个非EOF的非错误条件?

这是一个小型单线程程序。当将其馈送为2^30字符串作为输入(作为压力测试,发现此行为)时,发生了此错误。

用Linux上的GCC C99编译。

编辑

几天后,我投入了很多工作。i 使用git,因此它非常容易地使用复制代码创建另一个分支或标签,但是我没有观察到这种良好的做法。在与我认为是越野车犯的合作时,我的O.S.刚开始使用RC 137杀死我的程序。

但是

CHUX的测试安全带显示了一个相关问题,该问题是可重复的,我想我可以将这个问题保留在主题上。

显示问题的测试线束。

此代码和OP之间的区别是始终显示errno的状态。


当出现内存外时,设置了errno,但是getline()返回了超过capacity的长度 - 非常奇怪 - 而不是-1。

如果是否合规,我会留下您对以下内容的解释。IMO不合规。如果由于getline()的任何原因设置了errno,我希望返回值为-1,除了ferror()或未在文件末期读取。

我怀疑由于递延内存分配而引起的问题。

返回值
在成功时,getline()getdelim()返回读取的字符数,包括定界符字符,但不包括终止null字节(' 0')。该值可用于处理行中的嵌入式null字节。

两个功能在未能读取线路(包括文件终止条件)时返回-1。如果发生错误,则将ERRNO设置为指示原因。

错误
Einval不良论点(n或linePtr为null,或者流无效)。
线缓冲区的INOMEM分配或重新分配失败。


代码还使用CR/LF与LF进行了实验,但似乎没有相关。


#include <errno.h>
#include <stdint.h>
#include <stdio.h>
int djtest(unsigned sh, unsigned long long a, bool crflag) {
  printf("sh:%2u a:%12llu crlf:%d   ", sh, a, crflag);
  FILE *stream = fopen("test.bin", "wb");
  if (stream == NULL) {
    return printf("error fopen(wb)n");
  }
  char buf[1024 * 1204];
  memset(buf, 'a', sizeof buf);
  while (a > 0) {
    unsigned long long m = a;
    if (m > sizeof buf) m = sizeof buf;
    size_t y = fwrite(buf, sizeof *buf, (size_t) m, stream);
    if (y != m) {
      return printf("error fwriten");
    }
    a -= m;
  }
  if (fputs(crflag ? "rn" : "n", stream)) {
    return printf("error fputsn");
  }
  if (fclose(stream)) {
    return printf("error fclosen");
  }

  stream = fopen("test.bin", "r");
  if (stream == NULL) {
    return printf("error fopen(r)n");
  }
  char* line = NULL;
  size_t capacity = 0;
  ssize_t n = getline(&line, &capacity, stream);
  int err = errno;
  printf("cap:%12zu ssize_t:%12lld feof:%d ferror:%d errno:%2d line:%p %s   ", //
      capacity, (long long)n, feof(stream), ferror(stream), err, (void*)line, strerror(err));
  free(line);
  if (fclose(stream)) {
    return printf("error fclosen");
  }
  return printf("Finn");
}
int main() {
  for (unsigned sh = 28; sh < 31; sh++) {
    unsigned long long a = 1ull << sh;
    djtest(sh, a, 0);
    djtest(sh, a, 1);
    fflush(stdout);
    a *= 2;
  }
  printf("All donen");
  return 0;
}

输出

sh:28 a:   268435456 crlf:0   cap:   536870912 ssize_t:   268435457 feof:0 ferror:0 errno: 0 line:0xbff20008 No error   Fin
sh:28 a:   268435456 crlf:1   cap:   536870912 ssize_t:   268435458 feof:0 ferror:0 errno: 0 line:0xbff20008 No error   Fin
sh:29 a:   536870912 crlf:0   cap:  1073741824 ssize_t:   536870913 feof:0 ferror:0 errno: 0 line:0x1ff80008 No error   Fin
sh:29 a:   536870912 crlf:1   cap:  1073741824 ssize_t:   536870914 feof:0 ferror:0 errno: 0 line:0x1ff80008 No error   Fin
sh:30 a:  1073741824 crlf:0   cap:  1073741824 ssize_t:  1610088455 feof:0 ferror:0 errno:12 line:0x1ff80008 Cannot allocate memory   Fin
sh:30 a:  1073741824 crlf:1   cap:  1073741824 ssize_t:  1610088455 feof:0 ferror:0 errno:12 line:0x1ff80008 Cannot allocate memory   Fin
All done

GNU C11(GCC)版本6.4.0

相关内容

  • 没有找到相关文章

最新更新