realloc(): invalid next size when reallocating to make space for strcat on char * [duplicate]

realloc(): invalid next size when reallocating to make space for strcat on char * [duplicate]






This question already has answers here:
                            
                        



Facing an error “*** glibc detected *** free(): invalid next size (fast)”

                                    (2 answers)
                                

Closed 5 years ago.


I am getting invalid memory error on following code:
printf(" %s\n","FINE 5");
printf("%s LENGTH IS: %d\n","FINE 6",strlen(": "));
buffer = (char *)realloc(buffer, strlen(buffer)* sizeof(char) + (strlen(": ")+1)* sizeof(char));
printf(" %s\n","FINE 7");
strcat(buffer, ": \0");

Output:

FINE 5  FINE 6 LENGTH IS: 2
* glibc detected * ./auto: realloc(): invalid next size: 0x08cd72e0 ***
  ======= Backtrace: ========= /lib/tls/i686/cmov/libc.so.6(+0x6b591)[0x6dd591]

The point to note here is Fine 7 is never printed. and invalid next size error on every run is at the same location.
Found this relavent

Solutions/Answers:

Answer 1:

This error occurs because some other part of your code has corrupted the heap. We can’t tell you what that error is without seeing the rest of the code.

The fact that FINE 7 is not printed tells you that realloc is failing. And that failure must be because buffer is invalid due to a heap corruption earlier in the execution.


Orthogonal to your actual problem, sizeof(char) is 1 by definition so it makes sense to remove it from the code.

Answer 2:

As David Heffernan points out, your root problem must be a wild pointer elsewhere in your code smashing the heap.

There are several other things worth thinking about in this code snippit, though:

  1. No need for sizeof (char) in the new size expression, as sizeof (char) is, by definition, 1.

  2. Never assign the return from realloc directly back to the only pointer to the buffer you’re reallocating. If realloc returns NULL on an error, you’ll lose your pointer to the old buffer, and gain your very own memory leak. You always want to do the appropriate equivalent of:

    footype *p = realloc(oldbuff, newsize);
    if (!p) {
        handle_error();
    } else {
        oldbuff = p;
    }
    
  3. In C, void * will automatically be converted to the correct type on assignment, there is no need to cast. Further, by casting, in some cases you won’t get helpful error messages when you forget to include the declaration of the function in question.

  4. String literals include an implied nul terminator. You wanted to say:

    strcat(buffer, “: “);

On the up side, strcat will stop at the first nul character, so no harm in this case.

Answer 3:

(char *)realloc(buffer, strlen(buffer)* sizeof(char) + (strlen(": ")+1)* sizeof(char));

Should be

(char *)realloc(buffer, (strlen(buffer) + strlen(": ") + 1) * sizeof(char));

should it not? You’re math for the length of the string is wrong.

References