Realloc allocates memory that is already in use

This topic is 4390 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

Hi, I've got a problem with realloc. It took me a while to figure it out, but finally I know what's happening. I've allocated a space with calloc, 3 pointers (12 bytes), address: 6777244 After that, I've allocated a space with malloc, address: 6777260 Then I reallocate the first space to 4 pointers, 16 bytes. But instead of moving the pointer, it just gives me 6777260 as the fourth pointer space. So when I fill it, I'm writing in my malloced space!! (6777244 + 16 = 6777260) The manual says that realloc moves the pointer, but it doesn't happen. What could be the problem? Gerben VV

Share on other sites
Can we see some code? Most likely you're corrupting the heap somehow.

Share on other sites
Well, possibly I'm bad in mathematics but you got xx44 and xx60 as adresses. This means that between them there are 16 bytes. If you realloc something, and there is still enough space, absolutely nothing will happen with the pointer. That's why realloc exists in the 1st place it is an optimization to

char *p = (char *)malloc(12);
...
char *tmp = p;
p = (char *)malloc(16);
memcpy(p, tmp, 12);
free(tmp);
...

because if it is detected by the internal memory management of the heap that there is still sufficient space, nothing is done.

Share on other sites
How could I corrupt the heap in C?
The code is actually quait complicated, couse I'm using Flex and Bison, but here's some code lines:

var1 = (mystruct *) malloc(sizeof(mystruct));

returns 6777260

and somewhere else:

var2 = (mystruct2 **) calloc(3, sizeof(mystruct *));

returns 6777244

realloc:

var2 = (mystruct2 **) realloc(var2, 4);

returns 6777244

so writing the fourth pointer, will result in var1 being overwritten:

var2[3] = &somevar;

Gerben VV

Share on other sites
Whoops, found the problem already, realloc doesn't want the entry count unlike calloc, but the bytecount. so 4 in my realloc should be 4 * sizeof(mystruct *)

Share on other sites
Quote:
 Original post by gerbenvvWhoops, found the problem already, realloc doesn't want the entry count unlike calloc, but the bytecount. so 4 in my realloc should be 4 * sizeof(mystruct *)

Actually, it should either be

var2.resize(4);

or

void *temp = realloc(var2, 4*sizeof *var2);
if (!temp) { /* handle error */ }
var2 = temp;

or maybe

mystruct2 *temp = new mystruct2[4];
std::copy(var2, var2 + 3, temp);
delete[] var2;
var2 = temp;

Share on other sites
This is C, not C++. None of those things work in C.

Share on other sites
Quote:
 Original post by DeyjaThis is C, not C++. None of those things work in C.

The middle one would if the syntax was correct... but you're right :-).

Share on other sites
Quote:
 Original post by DeyjaThis is C, not C++. None of those things work in C.

If this is C, then it's bad form. Casting realloc, and void pointers in general, is a no-no in C because it makes the code more brittle and can hide a rare-but-hard-to-find bug. Casting void pointers is required in C++, not C.

I assumed he was casting it because he was compiling it as C++ and was using realloc() because he was using a malloc()'d buffer (possibly from code he can't control). The suggestions amounted to alternatives to malloc()'d buffers (the first and third) or writing good C (the second).

Quote:
 Original post by MaulingMonkeyThe middle one would if the syntax was correct... but you're right :-).

#include <stdlib.h>struct {  int a;  double b;} *var2 = NULL;int main(void) {  var2 = malloc(3*sizeof *var2);  if (!var2) { return EXIT_FAILURE; }  {    void *temp = realloc(var2, 4*sizeof *var2);    if (!temp) { /* handle error */ }    var2 = temp;  }  free(var2);  return EXIT_SUCCESS;}

Compiles fine for me with "gcc -ansi -pedantic -Wall -W" and gives no warnings. It would be slightly more conventional to not introduce the new block, but it avoids people nit-picking about the "void *" in front of temp not being legal pre-C99 without the new block. Pre-C99, all variable must be declared at the start of the function, so more conventional pre-C99 code would put "void *temp = NULL;" at the start of the function and remove the "void *" in front of it later.

Share on other sites
Quote:
 Original post by gerbenvv...The manual says that realloc moves the pointer, but it doesn't happen.What could be the problem?

realloc doesn't always return a different pointer. If it can fit the new allocation in the old space, it may return the original pointer (as it did in your case).

• 10
• 17
• 9
• 14
• 41