trouble in freeing memory using realloc

C

cijo

Hi,

My program has a pointer to a structure declared locally inside a
function to which memory is allocated using malloc and reallocated
later using realloc, and when I try to free the memory at the end of
the function, the program breaks down. While debugging, I find that the
address to which the pointer is pointing is changed during one of the
realloc calls. But as per the documentation on realloc, the change of
address is perfectly normal. Some of my colleagues say the failure in
'free'ing the memory is due to some bug in 'realloc'. I find it hard to
believe though. Is it dependent on the compiler (the IDE is MS Visual
Studion .NET 2003) or could there be something wrong with my code?
 
E

Eric Sosman

cijo said:
Hi,

My program has a pointer to a structure declared locally inside a
function to which memory is allocated using malloc and reallocated
later using realloc, and when I try to free the memory at the end of
the function, the program breaks down. While debugging, I find that the
address to which the pointer is pointing is changed during one of the
realloc calls. But as per the documentation on realloc, the change of
address is perfectly normal. Some of my colleagues say the failure in
'free'ing the memory is due to some bug in 'realloc'. I find it hard to
believe though. Is it dependent on the compiler (the IDE is MS Visual
Studion .NET 2003) or could there be something wrong with my code?

There could be something wrong with your code.

Try distilling the problem down to a short but complete
and compilable example that shows the trouble, and post
that example. It is astonishing how much better my crystal
ball works when I don't need to consult it ...
 
A

Artie Gold

cijo said:
Hi,

My program has a pointer to a structure declared locally inside a
function to which memory is allocated using malloc and reallocated
later using realloc, and when I try to free the memory at the end of
the function, the program breaks down. While debugging, I find that the
address to which the pointer is pointing is changed during one of the
realloc calls. But as per the documentation on realloc, the change of
address is perfectly normal. Some of my colleagues say the failure in
'free'ing the memory is due to some bug in 'realloc'. I find it hard to
believe though. Is it dependent on the compiler (the IDE is MS Visual
Studion .NET 2003) or could there be something wrong with my code?

Show us the smallest compilable snippet of code that exhibits the
behavior you describe -- otherwise how could *anyone* tell what's going on.

Be advised, however, that failures related to malloc/realloc/free are
usually due to the corruption of your free store, usually due to writing
outside the bounds of allocated memory.

HTH,
--ag
 
C

cijo

Hope this helps...:
typedef struct rangeElt_t
{
unsigned long startRange;
unsigned long endRange;
unsigned long startGIndex;
}rangeElt;

rangeElt *rangeEltBuf = NULL;

int _npdf_decodeCharmap(int ttfid, FILE *fcmapOut)
{
........
........
rangeEltBuf = (rangeElt *)malloc(CHUNK_SIZE *
sizeof(rangeElt));
if(rangeEltBuf == NULL)
{
/* error handling */
}

for (j = 1; j < i; j++) /*value of i determined at run time */
{
numRange++;
if(CHUNK_SIZE - numRange == 1)
{
rangeEltBuf = (rangeElt *)realloc(rangeEltBuf, ((numRange+
CHUNK_SIZE) * sizeof(rangeElt)));
if(rangeEltBuf == NULL)
{
/* error handling */
}
}
..................

}

if(rangeEltBuf != NULL)
{
free(rangeEltBuf); /* the program fails here */
rangeEltBuf = NULL;
}

}
 
M

Michael Mair

cijo said:
Hope this helps...:

Please quote a minimum of context -- some messages reach some servers
late or never, so it is possible that someone who could help you
cannot because he misses the context...
typedef struct rangeElt_t
{
unsigned long startRange;
unsigned long endRange;
unsigned long startGIndex;
}rangeElt;

rangeElt *rangeEltBuf = NULL;

int _npdf_decodeCharmap(int ttfid, FILE *fcmapOut)
{
.......
.......
rangeEltBuf = (rangeElt *)malloc(CHUNK_SIZE *
sizeof(rangeElt));

Note that the cast is unnecessary and potentially dangerous
(it can hide an error); the canonical use of malloc() is

rangeEltBuf = malloc(CHUNK_SIZE * sizeof *rangeEltBuf);

Using sizeof with the dereferenced variable has the advantage
that in the case of a type change you have not to replace and
potentially miss the cast expression.
if(rangeEltBuf == NULL)
{
/* error handling */
}

for (j = 1; j < i; j++) /*value of i determined at run time */
{
numRange++;
if(CHUNK_SIZE - numRange == 1)
{
rangeEltBuf = (rangeElt *)realloc(rangeEltBuf, ((numRange+
CHUNK_SIZE) * sizeof(rangeElt)));
if(rangeEltBuf == NULL)
{
/* error handling */
}

This is wrong. Correct usage for realloc():

rangeElt *tmp;
tmp = realloc(rangeEltBuf, (numRange+ CHUNK_SIZE)
* sizeof *rangeEltBuf);
if (tmp==NULL)
{
/* rangeEltBuf is still a valid pointer to the original storage,
** so you can do some error handling or at least dump what you
** have up to now. Otherwise, you would have lost the original
** pointer and caused a memory leak */
}
else
rangeEltBuf = tmp;
}
..................

}

if(rangeEltBuf != NULL)
{
free(rangeEltBuf); /* the program fails here */

This is strange and may come from yet another error source
-- are you maybe doing some other dynamic memory allocation?

Try creating a minimal example.
rangeEltBuf = NULL;
}

}

Cheers
Michael
 
E

Eric Sosman

cijo said:
Hope this helps...:
[...]

Not very much. I suggested that you should distill the
code down to a "short but complete and compilable" example
that demonstrates the problem. You've done pretty well with
the "short" part, but didn't pay much attention to "complete"
or "compilable." Those two words were not airy persiflage;
they were important.

"Doctor, it hurts!"
"Where does it hurt?"
"Somewhere in my body!"
"(Sigh.) Take two aspirin and call me in the morning."

Ah, well. I'll do my best with what you've provided, and
based on what you've provided I think the error is here:
.......
.......

Fix those two lines and the others like them, and all will
be well. Good luck!
 
M

Martin Ambuhl

cijo said:
Hope this helps...:

[followed by code using C++-style malloc-mangling and identifiers
reserved to the implementation, while failing to declare needed
variables, failing to define constants, and generally providing
non-compilable mush.]

There is no way to reliably diagnose your problem from the "code" you
posted. However, note the added 'else' in the cleaned-up version below.
It is possible that you have misdiagnosed where your problem occurs.

#include <stdlib.h>

#define CHUNK_SIZE 1024

typedef struct rangeElt_t
{
unsigned long startRange;
unsigned long endRange;
unsigned long startGIndex;
} rangeElt;

rangeElt *rangeEltBuf = NULL;

int npdf_decodeCharmap(void)
{
size_t i = 0, j, numRange = 0;
rangeEltBuf = malloc(CHUNK_SIZE * sizeof *rangeEltBuf);
if (rangeEltBuf == NULL) {
/* error handling */
}
else /* mha: NOTE added 'else' */
for (j = 1; j < i; j++) {
numRange++;
if (CHUNK_SIZE - numRange == 1) {
rangeEltBuf =
realloc(rangeEltBuf, (numRange + CHUNK_SIZE)
* sizeof *rangeEltBuf);
if (rangeEltBuf == NULL) {
/* error handling */
}
}
}
if (rangeEltBuf) {
free(rangeEltBuf);
rangeEltBuf = NULL;
}

}
 
C

CBFalconer

cijo said:
My program has a pointer to a structure declared locally inside a
function to which memory is allocated using malloc and reallocated
later using realloc, and when I try to free the memory at the end of
the function, the program breaks down. While debugging, I find that the
address to which the pointer is pointing is changed during one of the
realloc calls. But as per the documentation on realloc, the change of
address is perfectly normal. Some of my colleagues say the failure in
'free'ing the memory is due to some bug in 'realloc'. I find it hard to
believe though. Is it dependent on the compiler (the IDE is MS Visual
Studion .NET 2003) or could there be something wrong with my code?

You may be keeping stale pointer copies. You should have something
like this:

T *ptr, *temp;

if (!(ptr = malloc(sizeof *ptr))) failureaction();
else {
muckAboutWith(ptr);
if ((temp = realloc(ptr, newsize))) ptr = temp;
else {
announceReallocFailureUsingOld();
}
/* Here a NULL in temp means realloc failed */
moreMuckingWith(ptr);
}
free(ptr);

Noting that a successful realloc replaces ptr, and the old value
will never be seen again.

--
Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://www.eskimo.com/~scs/C-faq/top.html>
<http://benpfaff.org/writings/clc/off-topic.html>
<http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/> (C99)
<http://www.dinkumware.com/refxc.html> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
 
C

CBFalconer

cijo said:
typedef struct rangeElt_t
{
unsigned long startRange;
unsigned long endRange;
unsigned long startGIndex;
}rangeElt;

rangeElt *rangeEltBuf = NULL;

int _npdf_decodeCharmap(int ttfid, FILE *fcmapOut)
{
.......

What part of Sosmans:

"Try distilling the problem down to a short but complete and
compilable example that shows the trouble, and post that example."

is incomprehensible to you? What part of "quote context" do you
fail to understand?

--
Some useful references about C:
<http://www.ungerhu.com/jxh/clc.welcome.txt>
<http://www.eskimo.com/~scs/C-faq/top.html>
<http://benpfaff.org/writings/clc/off-topic.html>
<http://anubis.dkuug.dk/jtc1/sc22/wg14/www/docs/n869/> (C99)
<http://www.dinkumware.com/refxc.html> (C-library}
<http://gcc.gnu.org/onlinedocs/> (GNU docs)
 
G

glen herrmannsfeldt

cijo wrote:

(snip)
for (j = 1; j < i; j++) /*value of i determined at run time */
{
numRange++;
if(CHUNK_SIZE - numRange == 1)
{
rangeEltBuf = (rangeElt *)realloc(rangeEltBuf, ((numRange+
CHUNK_SIZE) * sizeof(rangeElt)));
if(rangeEltBuf == NULL)
{
/* error handling */
}
}
..................

}

I might have missed it, or you might not have posted it.
You reallocate to numRange+CHUNK_SIZE, but only test against
CHUNK_SIZE, so I believe it won't reallocate a second time,
even if it needs to. I believe, then, that you are writing
outside the allocated space which can easily make free() crash.

The information needed to keep track of malloc() space is usually
written just before the space you use. If you write over that,
malloc() or free() often crash.

-- glen
 
M

Malcolm

cijo said:
Some of my colleagues say the failure in
'free'ing the memory is due to some bug in 'realloc'. I find it hard to
believe though. Is it dependent on the compiler (the IDE is MS Visual
Studion .NET 2003) or could there be something wrong with my code?
Unthinkable that even Microsoft would release a C compiler with a buggy
realloc(). Changing compliers may make the problem go away, for a while,
because you will have corrupted the compiler-dependent control information
that malloc() and free() use to keep track of blocks.
Try using a tool like "boundschecker" or a malloc() library with better
diagnostics.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,581
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top