奇怪的free()无效指针C.

时间:2016-03-30 17:08:33

标签: c pointers malloc free realloc

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

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

这是输出:

{{1}}

我也尝试用valgrind调试它(它告诉我分配器试图释放9个字节,而字符总和是8,奇怪没有?)和gdb但没有任何效果。 input.txt的第一行是“HOME 2 A 8 D \ n”

3 个答案:

答案 0 :(得分:7)

第一次执行这些行

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

你获得1个指针的内存(j为0)。这为您在

函数末尾写入的结束NULL留下了空间
bufs[j] = 0;

所以你写的是超出分配的内存,因此有未定义的行为。同样,每次延长缓冲区长度。

答案 1 :(得分:6)

bufs[j] = 0;末尾的read_and_filter写入未分配的内存。您永远不会realloc - 为您的bufs添加0

答案 2 :(得分:0)

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

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

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

据valgrind说,以下没有记忆丧失。

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("%s\n", bptr);
  free(bptr);
  return 0;

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