在 getline( &buff, &len, f ) 调用后使用 len 参数进行比较导致它在下一次调用时崩溃

using len argument to getline( &buff, &len, f ) for comparison after its call causes it to crash on next call

以下错误仅在循环的第二次迭代时出现。

sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed.

这是循环的相关部分。

   char *buff = NULL ;
   size_t len ;
   size_t cnt = 0 ;


while( getline( &buff, &len, f ) > 1 )
   {

      // fprintf(stderr, "help1\n");
      // We read a last name (with the newline)
      person *p = malloc(sizeof(person)); // - get memory for person

      for (int i=0; i<len; i++){
          p->first[i]=buff[i];
      }
      p->first[len-1]='[=11=]';

将比较更改为

for (int i=0; i<strlen(buff); i++)

导致问题消失。有谁知道为什么会这样? p->first 似乎分配正确,因为您可以在循环完成后打印它。

是什么让您相信 getline() 分配的缓冲区长度与 getline() 读取的字符串长度相同? – 安德鲁·亨勒

问题可能是您在 struct person 中分配了一个固定大小的 char 数组(您未能显示其声明)并且您 运行 已经结束了.试试像

for (int i = 0; i < len && i < sizeof(p->first)-1; ++i)
    p->first[i] = buff[i];
p->first[sizeof(p->first) - 1] = '[=10=]';

确保不超过 struct person

中的数组大小

我发现您的代码存在一些问题。

大的是什么len?它是如何定义的?它代表什么?我假设 len 是缓冲区的长度,在循环比较中使用它是不正确的。不能保证字符串每次都会填满缓冲区。有几种方法可以解决这个问题。

while( getline( &buff, &len, f ) > 1 )
   {
      char ch;

      // fprintf(stderr, "help1\n");
      // We read a last name (with the newline)
      person *p = malloc(sizeof(person)); // - get memory for person

      for (int i=0; i<len; i++){
          ch = buff[i];
          p->first[i]=ch;
          if (ch == 0x00) break;
      }
      // p->first[len-1]='[=10=]';

第二种解决方法是:

while( getline( &buff, &len, f ) > 1 )
   {
      size_t x = strlen(buff);
      // fprintf(stderr, "help1\n");
      // We read a last name (with the newline)
      person *p = malloc(sizeof(person)); // - get memory for person

      for (int i=0; i<x; i++){
          p->first[i]=buff[i];
      }
      p->first[len-1]='[=11=]';

我个人比较喜欢第一种方式,因为我觉得效率更高。它将最多复制 len 个字节,但如果在此之前遇到终止 null,它将跳出循环。比较在 AFTER 复制完成,因此如果它是空值,则在循环终止之前将复制空值。

第二个方法调用strlen然后进入循环,所以你是运行两个循环(strlen是用while循环实现的)。所以第一种方法基本上是一个strlen和strncpy组合成一个循环。