0

当我编译并运行这段代码时,我得到一个错误。错误信息是:

realloc(): invalid next size: 0x0000000002119010

该文件input大约有4000字。

我调试了它,但我找不到任何问题。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#define BUF_LEN 10   //buf length

int main(int argc, char *argv[])
{
  int file_d;                     //file descriptor
  char *ct_head;                  //content_first_char
  char *content;
  ssize_t read_len = BUF_LEN;     //had read length
  int mem_block_count = 0;

  file_d = open("input", O_RDONLY);

  if (file_d < 0)
    {
      perror("open");
      exit (1);
    }

  content = ct_head = (char *) malloc(sizeof(char) * BUF_LEN);
  mem_block_count = 1;

  while (read_len == BUF_LEN)
    {
      read_len = read(file_d, ct_head, BUF_LEN);
      if (read_len < 0)
        {
          perror("read");
          exit(2);
        }
      if (read_len == BUF_LEN)
        {
          ct_head = (char *)realloc(content, sizeof(char) *(++mem_block_count));
          ct_head = &content[(mem_block_count-1) * BUF_LEN];
        }
      else
        ct_head[read_len] = '\0';
    }
  printf("%s", content);

  close(file_d);
  free(content);
  return 0;
}
4

3 回答 3

0

你已经在这里得到了一些很好的答案,但这里有一些不适合评论的建议。在 C 中,sizeof(char)总是1。根据定义,它是 1,因此它与 using 一样多余(1 * BUF_LEN)。同样在 C 中,您不必 [也不应该] 强制转换malloc. 这样做可以掩盖一个基本错误1 ​​。

如果要根据类型的大小分配空间,请使用:

ct_head = malloc(sizeof(*ct_head) * BUF_LEN);

这样,如果类型发生ct_head变化,您仍然可以分配足够的空间,而无需更改对mallocand的所有调用realloc

1. 如果您没有为 包含适当的标头malloc,则 C 编译器将假定malloc返回int,这可能会导致在平台上的大小int与指针类型的大小不同的问题。此外,从整数类型到指针类型的转换是实现定义的。

于 2012-04-25T09:37:11.330 回答
0

我不确定你的问题是什么,但这些行:

    ct_head = (char *)realloc(content, sizeof(char) *(++mem_block_count));
    ct_head = &content[(mem_block_count-1) * BUF_LEN];

非常狡猾。在第一行之后,ct_head指向重新分配的块并content指向垃圾。然后第二行读取content并重新分配ct_head- 泄漏重新分配的内存。

我怀疑您的程序中可能只是内存损坏?

我认为

ct_head = (char *)realloc(content, sizeof(char) *(++mem_block_count));

应该:

content = (char *)realloc(content, sizeof(char) *(++mem_block_count) * BUF_LEN);
if (content == NULL)
{
    // do something if the realloc fails
}
于 2012-04-25T08:39:04.937 回答
0

第一次使用 realloc 时,它只分配 2 个字节,因为在进入调用时,sizeof(char)它是 1 并且mem_block_count也是 1(然后它被预递增到 2)。

这意味着下一次读取将超出它分配的缓冲区。BUF_LEN我怀疑您还需要在 realloc 中乘以。

编辑

我刚刚意识到,更糟糕的是:在将内容分配给 2 个字节之后,您将设置ct_headBUF_LEN内容开头之外的字节。这意味着您的读取会覆盖完全在缓冲区之外的区域。

于 2012-04-25T08:39:10.003 回答