Sign in to follow this  
gerbenvv

Realloc allocates memory that is already in use

Recommended Posts

gerbenvv    116
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 this post


Link to post
Share on other sites
starmole    126
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 this post


Link to post
Share on other sites
gerbenvv    116
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 this post


Link to post
Share on other sites
gerbenvv    116
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 this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Quote:
Original post by gerbenvv
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 *)


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;

depending on your needs.

Share this post


Link to post
Share on other sites
Way Walker    745
Quote:
Original post by Deyja
This 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 MaulingMonkey
The 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 this post


Link to post
Share on other sites
JohnBolton    1372
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).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this