user277465
user277465

Reputation:

realloc causes glibc error for array of pointers

I have some C code that contains an array of text that I'm trying to manipulate in the following manner :-

The code however, causes the following error :-

*** glibc detected *** ./crack: realloc(): invalid next size: 0x0000000001386010 ***
^Cmake: *** [run] Interrupt

The code is as follows :-

 // Replace all spaces with '\0'
  for ( i = 0; i < file_size; i++ ) {
    if ( temp_buffer[i] == ' ' || temp_buffer[i] == '\n' ) {
      while ( temp_buffer[i] == ' ' || temp_buffer[i] == '\n' ) {
        temp_buffer[i] = '\0';
      }
      j++;
    }
    if ( (j-1) % 3 == 0 ) {
      dictionary[k] = temp_buffer+i;
      k += 1;
      if ( k == dictionary_size ) {
        dictionary_size *= 2;
        printf("Going to realloc to %d\n", dictionary_size);
        dictionary = (char **)realloc(dictionary, dictionary_size);
      }
    }
  }

[EDIT] Based on the debugging statements I have, the very first realloc(to a size of 100) fails.

Upvotes: 0

Views: 98

Answers (2)

Remo.D
Remo.D

Reputation: 16522

You are allocating too little memory. The error is caused by trashing the memory (and you can never know which error will actually come out from trashed memory).

If you allocate dictionary_size bytes you have room for dictionary_size/sizeof(char *) pointers.

Your if statement, instead, suggests that you think you have space for dictionary_size pointers, which is not the case.

Change your malloc/realloc to something like:

dictionary = (char **)realloc(dictionary, dictionary_size * sizeof(char *));

btw, you don't need to cast the return of realloc.

As a final suggestion, considering that realloc(NULL, ...) is equivalent to malloc(), it might be easier to write something like:

  dictionary = NULL;
...  other code here ...
  if ( k >= dictionary_size ) {
    while (k >= dictionary_size) dictionary_size *= 2;
    printf("Going to realloc to %d\n", dictionary_size);
    dictionary = (char **)realloc(dictionary, dictionary_size * sizeof(char *));
  }
  dictionary[k++] = temp_buffer+i;
... etc ...

So you are absolutely sure that whatever k is, you have enough room for dictionary[k].

Upvotes: 0

egur
egur

Reputation: 7970

dictionary_size is the element (pointer) count, not the allocation size. should be dictionary_size * sizeof(char*)

dictionary = realloc(dictionary, dictionary_size * sizeof(*dictionary)); // safer, 10x @alk

Or (less recommneded):

dictionary = realloc(dictionary, dictionary_size * sizeof(char*));       // clearer

Also check that dictionary_size is properly initialized.

Upvotes: 2

Related Questions