Sign in to follow this  
Madster

crash on realloc?

Recommended Posts

Ok, I'm getting a crash on realloc. I'm using SDL and the parachute isn't deployed, so it isn't a segfault. Are there any limitations on realloc? I realise that I'm probably overwriting over a buffer's limits somewhere, but still it strikes me as strange that it's crashing in the call to realloc, since at that moment it shouldn't matter how i'm dealing with the buffers Are there memory limits inherent to realloc? I'm only going around 250Mb of total data. thanks.

Share this post


Link to post
Share on other sites
realloc should return 0 if anything goes wrong, in which case the original pointer you gave it will still be intact.

Your problem is probably due to either buffer under/overflow, the pointer wasn't initialized, it's already been freed, or you didn't get the memory from malloc, calloc, or realloc.

It's probably buffer overflow, it's somewhat easy to mess up it's internal book keeping that way.

Share this post


Link to post
Share on other sites
Quote:
Original post by Madster
I realise that I'm probably overwriting over a buffer's limits somewhere
Bingo! There's your most probable cause.

At the risk of sounding like a broken record, I suggest making good use of asserts, especially when it comes to accessing arrays etc.

Share this post


Link to post
Share on other sites
i use realloc out of habbit just incase you didnt free something and malloc something that wasnt freed will crash

realloc keeps the original pointer unless the space wasnt big enough and it moves the entire memory segment (slow)
somewhere else

unless you are continuously enlarging or shrinking something i would just go malloc free

and realloc something that has been freed doesnt cause an error, it simply behaves as malloc

you may have realloc in a continuous loop and may be calling it too much over time, try just making a really big pointer and waiting till your done with it to mess with free or realloc, putting realloc in a loop does cause errors misteriously, its supposed to work but sometimes it doesnt


Share this post


Link to post
Share on other sites
i think it may be because calling it over and over again real fast doesnt give the operating sstem long enough to finish marking that previously used segment of ram as free, hince using up all the ram, give it time to free the memory

Share this post


Link to post
Share on other sites
Quote:
Original post by FreeTutorialNewbie
i think it may be because calling it over and over again real fast doesnt give the operating sstem long enough to finish marking that previously used segment of ram as free, hince using up all the ram, give it time to free the memory


That's complete and utter nonsense.

Quote:
Original post by FreeTutorialNewbie
and realloc something that has been freed doesnt cause an error, it simply behaves as malloc

you may have realloc in a continuous loop and may be calling it too much over time, try just making a really big pointer and waiting till your done with it to mess with free or realloc, putting realloc in a loop does cause errors misteriously, its supposed to work but sometimes it doesnt


And so is that.

Share this post


Link to post
Share on other sites
Function: realloc

Synopsis

#include <stdlib.h>
void *realloc(void *ptr, size_t size);
Description

The realloc function changes the size of the object pointed to by ptr to the size specified by size. The contents of the object shall be unchanged up to the lesser of the new and old sizes. If the new size is larger, the value of the newly allocated portion of the object is indeterminate. If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined. If the space cannot be allocated, the object pointed to by ptr is unchanged. If the realloc function returns a null pointer when size is zero and ptr is not a null pointer, the object it pointed to has been freed.

Returns

The realloc function returns either a null pointer or a pointer to the possibly moved allocated space. If the object has moved, ptr is a pointer that refers to freed space.

Share this post


Link to post
Share on other sites
Quote:
Original post by FreeTutorialNewbie
Otherwise, if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined.

Enigma

Share this post


Link to post
Share on other sites
Quote:
If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined.


lol..thats kinda saying it will work and it wont in the same definition

Share this post


Link to post
Share on other sites
No, it means on some compilers it may work, on others it may blow up, or even blow up after an update to the compiler it previously worked on. Either way undefined behavior means don't do it.

Share this post


Link to post
Share on other sites
No it's not. If the pointer is valid or is null the behaviour is defined. If the pointer is non-null but invalid (i.e. the pointer has been free'd or was not allocated by calloc, malloc or realloc then the behaviour is undefined. A free'd pointer is not the same as a null pointer.

Enigma

Share this post


Link to post
Share on other sites
Quote:
Original post by FreeTutorialNewbie
Quote:
If ptr is a null pointer, the realloc function behaves like the malloc function for the specified size. Otherwise, if ptr does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to the free or realloc function, the behavior is undefined.


lol..thats kinda saying it will work and it wont in the same definition


No, that's saying the behavior is undefined, meaning anything could happen from working like malloc() to returning 0 to crashing your program to frying you with a bolt of lightning. In other words, you shouldn't do it.

EDIT: Beaten to it :)

Share this post


Link to post
Share on other sites
Quote:
Original post by FreeTutorialNewbie
or how about...


if((lpdata=realloc(lpdata,int_size))==NULL){
if((lpdata=malloc(int_size))==NULL){
..total failure...

}}else{

..sucess...
}


More garbage. The problem is a crash not a realloc failure. The most likely cause is that a buffer overrun has rewritten book keeping information put inline with allocated memory, which will cause a bad dereference or assertion when the memory management system tries to access the corrupted bookkeeping information. Checking for a null return value 1) doesn't address the actual cause and 2) won't work since the crash will occur before the return.

Share this post


Link to post
Share on other sites
you are stuck between a rock and a hard place

•You allocate memory, and you free it, but because of a complicated control flow (many ifs, whiles and other constructs) you free a piece of memory twice. This corrupts the whole memory allocation system, and in a few milliseconds all the memory of your program can be a horrible mess.

•You allocate memory, you free it once, but you forget that you had assigned the memory pointer to another pointer, or left it in a structure, etc. This is the dangling pointer problem. A pointer that points to an invalid memory location.

^ some possible causes

also i found an "_msize" function that is supposed to be used to find the size of a memory block, i have no documentaion about it so i have never used it

but if you are never freeing the pointer then calling realloc over and over again is supposed to work, you may have other issues perhaps like trying to push an integer into the placeholder for a char or something whack

Share this post


Link to post
Share on other sites
_msize is defined in malloc.h as

size_t _msize(void *);

it basically is supposed to find the size of the block pointed to by the pointer

but when i did free before _msize it still returns the last allocated size before free, making it useless to check for 0 size being pointed to by the pointer

i was expecting

char *c=malloc(10);
free(c);
int _msize(c);

int should be 0 but is instead 10
making

if(!_msize(c)){
c=malloc(10);}

unuseable.

your only option it seems is to review your code

be aware that size_t is an unsigned int
so

int a=-1;
char *b=malloc(a);
its the same as
char *b=malloc(4294967296);
if a function you use to determine size is returning a result less than 0 or a nul result, realloc will crash













Share this post


Link to post
Share on other sites
ok..i found this in a tutorial written for the lcc win32 compiler
authored by Jacob Novia



Instead of using directly malloc/free here are two implementations of equivalent functions with some added safety features:
1Freeing NULL is allowed
Memory management strategies 127
2  Double freeing is made impossible.
3  Any overwrite immediately at the end of the block is checked for.
4  Memory is initialized to zero.
5  A count of allocated memory is kept in a global variable.

#define MAGIC 0xFFFF
#define SIGNATURE 12345678L
size_t AllocatedMemory;
void *allocate(size_t size)
{
register char *r;
register int *ip = NULL;
size += 3 * sizeof(int);
r = malloc(size);
if (r == NULL)
return r;
AllocatedMemory += size;
ip = (int *) r;
// At the start of the block we write the signature
*ip++ = SIGNATURE;
// Then we write the size of the block in bytes
*ip++ = (int) size;
// We zero the data space
memset(ip, 0, size - 3*sizeof(int));
// We write the magic number at the end of the block, just behind the data section
ip = (int *) (&r[size - sizeof(int)]);
*ip = MAGIC;
// Return a pointer to the start of the data area
return (r + 2 * sizeof(int));
}
void release(void *pp)
{
register int *ip = NULL;
int s;
register char *p = pp;
if (p == NULL) // Freeing NULL is allowed
return;
// The start of the block is two integers before the data.
p -= 2 * sizeof(int);
ip = (int *) p;
if (*ip == SIGNATURE) {
// Overwrite the signature so that this block can’t be freed again
*ip++ = 0;
s = *ip;
ip = (int *) (&p[s - sizeof(int)]);
if (*ip != MAGIC) {
ErorPrintf(“Overwritten block size %d”, s);
return;
}
*ip = 0;
AllocatedMemory -= s;
free(p);
}
else {
/* The block has been overwritten. Complain. */
ErrorPrintf(“Wrong block passed to release”);
}
}

The allocate function adds to the requested size space for 3 integers.
1) The first is a magic number (a signature) that allows the identification of this block as a block allocated by our allocation system.
2) The second is the size of the block. After this two numbers, the data follows.
3) The data is followed by a third number that is placed at the end of the block. Any memory overwrite of any block will overwrite probably this number first. Since the “release” function check for this, we will be able to detect when a block has been overwritten.
At any time, the user can ask for the size of total allocated memory (valid blocks in circulation)
by querying the AllocatedMemory variable.
The “release function” accepts NULL (that is ignored). If the pointer passed to it is not NULL, it will check that it is a valid block, and that the signature is still there, i.e. that no memory overwrites have happened during the usage of the block.


-im not sure it it is compatible with all compilers, but i figure it can be modified to fit your needs

Share this post


Link to post
Share on other sites
FreeTutorialNewbie, don't forget to use [ source ] tags. As for those 5 things, I can honestly say that you shouldn't assume any of those things work, 'specially if you expect other people to compile your code. My method of coding is to assume everything doesn't work, that way you don't encounter problems associated with assuming things that may or may not be true (like those 5 things).

Share this post


Link to post
Share on other sites
Whoa so many good replies! Thanks everyone, now I know it's definitely a buffer overrun somewhere. I'll get on that. :)

Share this post


Link to post
Share on other sites
Quote:
Original post by FreeTutorialNewbie
_msize is defined in malloc.h as

size_t _msize(void *);

_msize isn't standard. There is, for various reasons, no standard way to find out how large a block of allocated memory is.
Quote:
be aware that size_t is an unsigned int

No, it isn't.

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