0

When I compile and run this code, I get an error. The error message is:

realloc(): invalid next size: 0x0000000002119010

The file input has about 4000 words.

I debugged it, but I can not find any problem.

#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;
}
ArjunShankar
  • 23,020
  • 5
  • 61
  • 83
thlgood
  • 1,275
  • 3
  • 18
  • 36
  • In `realloc`, shouldn't it be `(char *)realloc(content, sizeof(char) *(++mem_block_count) * BUF_LEN);`? – Naveen Apr 25 '12 at 08:34
  • After your realloc, content may be invalid (since it may have been freed by the realloc). I think you should assign the pointer returned by realloc to content, not ct_head – qbert220 Apr 25 '12 at 08:39
  • 1
    Be careful, [do not cast the return type of your malloc/realloc functions](http://stackoverflow.com/a/605858/1151654). – Eregrith Apr 25 '12 at 10:03

3 Answers3

0

I'm not sure what your problem is but these lines:

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

Are very dodgy. After the first line, ct_head points to the realloced block and content points to garbage. Then the second line reads content and re-assigns ct_head - leaking the realloced memory.

I suspect you may just have memory corruption in your program?

I think

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

should be:

content = (char *)realloc(content, sizeof(char) *(++mem_block_count) * BUF_LEN);
if (content == NULL)
{
    // do something if the realloc fails
}
Douglas Leeder
  • 52,368
  • 9
  • 94
  • 137
0

The first time you use realloc, it allocates only 2 bytes because, going into the call, sizeof(char) is 1 and mem_block_count is also 1 (and it is then pre-incremented to 2).

This means the next read will overrun the buffer it has allocated. I suspect you need to also multiply by BUF_LEN in your realloc.

Edit

I've just realised, it's even worse: straight after allocating content to 2 bytes, you set ct_head to BUF_LEN bytes beyond the start of content. This means your read overwrites an area that is totally outside the buffer.

JeremyP
  • 84,577
  • 15
  • 123
  • 161
0

You've already got some good answers here, but here's a little bit of advice that won't fit in a comment. In C, sizeof(char) is always 1. It is 1 by definition, so it is as redundant as using (1 * BUF_LEN). Also in C, you don't have to [and shouldn't] cast the result of malloc. Doing so can mask a fundamental error1.

If you want to allocate space depending on the size of a type, use:

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

That way, if the type of ct_head changes, you'll still be allocating enough space, without having to change all the calls to malloc and realloc.

1. If you do not include the appropriate header for malloc, then a C compiler will assume that malloc returns int, and this may cause issues on platforms where the size of an int differs from the size of a pointer type. Also, conversions from integer types to pointer types are implementation-defined.

dreamlax
  • 93,976
  • 29
  • 161
  • 209