奇怪的 free() 无效指针 C



我对这段我修改了很多次的代码有问题(但错误总是出现(:似乎在释放"过滤器"的最后一个索引时出错

char** read_and_filter(int fd) {
  char buf[MAXLENGTH];
  char **bufs=NULL;
  char ch;
  int j = 0, len = 0, t = 0;
  while (!t && read(fd,&ch,1) == 1) {
    switch (ch) {
    case 'n':
      t = 1;
    case ' ':
      bufs = realloc(bufs, (j+1)*sizeof(char*));
      bufs[j++] = strndup(buf,len);
      memset(buf,0,len);
      len = 0;
      break;
    default:
      buf[len++] = ch;
    }
  }
  bufs[j] = 0;
  return bufs;
}
int main(int argc, char **argv) {
  char **filter;
  int i,fd = open("input.txt",O_RDONLY);
  filter = read_and_filter(fd);
  for(i = 0; filter[i]; i++) {
    printf("%sn",filter[i]);
    free(filter[i]);
  }
  return 0;
}

这是输出:

0x1521030
HOME
0x1521050
2
0x1521070
A
0x1521010
8
0x15210c0
D
*** Error in `./test': free(): invalid pointer: 0x00000000015210c0 ***

我还尝试使用 valgrind 调试它(它告诉我分配器试图释放 9 字节,而字符总和为 8,奇怪不是吗?(和 gdb,但没有任何效果。输入的第一行.txt是"HOME 2 A 8 D">

第一次执行这些行时

bufs = realloc(bufs, (j+1)*sizeof(char*));
bufs[j++] = strndup(buf,len);

获取 1 个指针的内存(j 为 0(。这不会为您在函数末尾编写的结束NULL留下空间

bufs[j] = 0;
因此,

您正在超出分配的内存进行写入,因此具有未定义的行为。同样,每次扩展缓冲区长度时。

read_and_filter结束时的bufs[j] = 0;写入未分配的内存。你从来没有realloc过你的bufs,因为那额外的0.

内存泄漏发生在两个地方 - strdup 和 realloc

一个答案是使用 malloc 为 main 中的缓冲区进行初始内存分配,然后将指向已分配内存的指针传递给函数。然后,该函数可以重新分配缓冲区,并将数据复制到其中。

从函数返回时,main 可以直接从缓冲区访问数据,因为它有一个指向它的有效指针,然后可以在关闭之前释放该内存。

根据瓦尔格林德的说法,以下没有记忆丧失。

void read_and_filter(int fd, char **bufs) {
  char buf[100];
  char ch;
  int j = 0, len = 0, t = 0;
  while (!t && read(fd,&ch,1) == 1) {
    switch (ch) {
    case 'n':
      t = 1;
    case ' ':
      *bufs = realloc(*bufs, (j + 2)*sizeof(char*));
      strncpy(bufs[j++], buf, len);
      memset(buf,0,len);
      len = 0;
      break;
    default:
      buf[len++] = ch;
    }
  }
  bufs[j] = 0;
  return;
}
int main(int argc, char **argv) {
  char *bptr = malloc(1);
  int fd = open("input.txt", O_RDONLY);
  read_and_filter(fd, &bptr);
  printf("%sn", bptr);
  free(bptr);
  return 0;
但是,

我不能确定这是否完全复制了OP的预期功能,但是整体方法确实可以解决内存问题。

相关内容

  • 没有找到相关文章

最新更新