Freeing memory allocated by another function


P

Praetorian

This is actually 2 questions:

The first one:
I have a function (FuncA) calling another (FuncB) with a set of
parameters which also includes an int * initialized to NULL before the
call.
Now FuncB looks at the other parameters and decides whether or not to
allocated memory to the int * passed to it (using calloc()). One of
the other parameters passed is a structure and if FuncB does allocate
memory it'll point one of the members of this structure to the int *
parameter.

void FuncA(.....)
{
struct param1;
int * param2;

FuncB(&param1, param2);
<do something>
if(param2!=NULL) {
free(param2);
}
}

void FuncB(struct *param1, int *param2)
{
if(<some conditions>) {
param2 = calloc(<some memory>);
param1->memberVar = param2;
}
}

Is this valid? Can the memory allocated within another function be
freed by a calling function as long as the original pointer variable
stays the same?

Now the second part:
I implemented the code above but it's showing me some strange results
when I breakpoint and watch the different variables in Visual Studio
2005.

Here's what I see:
Within FuncA -
param2 is NULL;
Within FuncB -
conditions for allocating memory evaluate to true.
memory is allocated and assigned to param2 (I'm not using calloc()
directly but through a library wrapper function that throws an error
if the allocation fails)
but param2 is still NULL (0x00000000) in the watch window.
however, when the line "param1->memberVar = param2;" executes it
(memberVar) has a valid address (it was previously NULL too).
I can even assign values using "param1->memberVar[0] = 1;" etc.
Back outside in FuncA
structure param1 is used by some other library functions to do
stuff. The values in memberVar are all valid and correct but param2 is
still NULL!
As a result FuncA cannot free the memory allocated to param2.

What's going wrong here?

Thanks in advance,
Ashish.
 
Ad

Advertisements

S

Spiros Bousbouras

This is actually 2 questions:

The first one:
I have a function (FuncA) calling another (FuncB) with a set of
parameters which also includes an int * initialized to NULL before the
call.
Now FuncB looks at the other parameters and decides whether or not to
allocated memory to the int * passed to it (using calloc()). One of
the other parameters passed is a structure and if FuncB does allocate
memory it'll point one of the members of this structure to the int *
parameter.

void FuncA(.....)
{
struct param1;

I'm not sure if the line above is legal but it
certainly doesn't do anything useful.
int * param2;

FuncB(&param1, param2);
<do something>
if(param2!=NULL) {
free(param2);
}

}

void FuncB(struct *param1, int *param2)

So param1 is a pointer to some structure but we
don't know which one ? Not legal I'm afraid.
{
if(<some conditions>) {
param2 = calloc(<some memory>);
param1->memberVar = param2;
}

}

Is this valid? Can the memory allocated within another function be
freed by a calling function as long as the original pointer variable
stays the same?

Yes it can be freed. It is not an issue of a variable
staying the same but of calling free() with a value
returned by calloc() , malloc() etc.
Now the second part:
I implemented the code above but it's showing me some strange results
when I breakpoint and watch the different variables in Visual Studio
2005.

Here's what I see:
Within FuncA -
param2 is NULL;
Within FuncB -
conditions for allocating memory evaluate to true.
memory is allocated and assigned to param2 (I'm not using calloc()
directly but through a library wrapper function that throws an error
if the allocation fails)
but param2 is still NULL (0x00000000) in the watch window.
however, when the line "param1->memberVar = param2;" executes it
(memberVar) has a valid address (it was previously NULL too).
I can even assign values using "param1->memberVar[0] = 1;" etc.
Back outside in FuncA
structure param1 is used by some other library functions to do
stuff. The values in memberVar are all valid and correct but param2 is
still NULL!
As a result FuncA cannot free the memory allocated to param2.

What's going wrong here?

You have not posted compilable code. You have not
even posted the declaration for the structure param1.
However based on what you posted I see no reason why
the assignment "param2 = calloc(<some memory>);" in
FuncB should modify param2 in FuncA. If you want param2
in FuncA to be modified then you need to pass a pointer
to param2 when you call FuncB , not param2 itself.
 
F

fred.l.kleinschmidt

This is actually 2 questions:

The first one:
I have a function (FuncA) calling another (FuncB) with a set of
parameters which also includes an int * initialized to NULL before the
call.
Now FuncB looks at the other parameters and decides whether or not to
allocated memory to the int * passed to it (using calloc()). One of
the other parameters passed is a structure and if FuncB does allocate
memory it'll point one of the members of this structure to the int *
parameter.

void FuncA(.....)
{
struct param1;
int * param2;

FuncB(&param1, param2);
<do something>
if(param2!=NULL) {
free(param2);
}

}

void FuncB(struct *param1, int *param2)
{
if(<some conditions>) {
param2 = calloc(<some memory>);
param1->memberVar = param2;
}

}

Is this valid?
<snip>

No, this is not correct. You need something like this:

void FuncA(.....)
{
struct somekind param1;
int *param2;

/* Initialize param2 in case FuncB doesn't */
param2 = NULL;

FuncB(&param1, &param2);
<do something>
if(param2!=NULL) {
free(param2);
}
}


void FuncB(struct sometype *param1, int **param2)
{
if(<some conditions>) {
*param2 = calloc(<some memory>);
param1->memberVar = *param2;
}
}

However, since you assign the allocation to param1->memberVar
(which I assume is an int*), it makes more sense to do this:

void FuncA(.....)
{
struct somekind param1;

FuncB(&param1);
<do something>
if(param1.memberVar!=NULL) {
free(param1.memberVar);
param1.memberVar=NULL;
}
}

void FuncB(struct sometype *param1)
{
if(<some conditions>) {
/* before doing this, you should worry
* about whether memberVar already points somewhere
*/
param1->memberVar = calloc(<some memory>);
}
else {
param1->memberVar = NULL;
}
}
 
P

Praetorian

This is actually 2 questions:
The first one:
I have a function (FuncA) calling another (FuncB) with a set of
parameters which also includes an int * initialized to NULL before the
call.
Now FuncB looks at the other parameters and decides whether or not to
allocated memory to the int * passed to it (using calloc()). One of
the other parameters passed is a structure and if FuncB does allocate
memory it'll point one of the members of this structure to the int *
parameter.
void FuncA(.....)
{
struct param1;

I'm not sure if the line above is legal but it
certainly doesn't do anything useful.
int * param2;
FuncB(&param1, param2);
<do something>
if(param2!=NULL) {
free(param2);
}

void FuncB(struct *param1, int *param2)

So param1 is a pointer to some structure but we
don't know which one ? Not legal I'm afraid.
{
if(<some conditions>) {
param2 = calloc(<some memory>);
param1->memberVar = param2;
}

Is this valid? Can the memory allocated within another function be
freed by a calling function as long as the original pointer variable
stays the same?

Yes it can be freed. It is not an issue of a variable
staying the same but of calling free() with a value
returned by calloc() , malloc() etc.


Now the second part:
I implemented the code above but it's showing me some strange results
when I breakpoint and watch the different variables in Visual Studio
2005.
Here's what I see:
Within FuncA -
param2 is NULL;
Within FuncB -
conditions for allocating memory evaluate to true.
memory is allocated and assigned to param2 (I'm not using calloc()
directly but through a library wrapper function that throws an error
if the allocation fails)
but param2 is still NULL (0x00000000) in the watch window.
however, when the line "param1->memberVar = param2;" executes it
(memberVar) has a valid address (it was previously NULL too).
I can even assign values using "param1->memberVar[0] = 1;" etc.
Back outside in FuncA
structure param1 is used by some other library functions to do
stuff. The values in memberVar are all valid and correct but param2 is
still NULL!
As a result FuncA cannot free the memory allocated to param2.
What's going wrong here?

You have not posted compilable code. You have not
even posted the declaration for the structure param1.
However based on what you posted I see no reason why
the assignment "param2 = calloc(<some memory>);" in
FuncB should modify param2 in FuncA. If you want param2
in FuncA to be modified then you need to pass a pointer
to param2 when you call FuncB , not param2 itself.

Spiros,
Sorry about the code I posted, I knew it was syntactically incorrect
but it was just meant to give you an idea of my problem. The problem
is indeed that I'm passing the pointer itself instead of a reference
to it. Thanks for your help.

Ashish.
 
Ad

Advertisements

P

Praetorian

<snip>

No, this is not correct. You need something like this:

void FuncA(.....)
{
struct somekind param1;
int *param2;

/* Initialize param2 in case FuncB doesn't */
param2 = NULL;

FuncB(&param1, &param2);
<do something>
if(param2!=NULL) {
free(param2);
}

}

void FuncB(struct sometype *param1, int **param2)
{
if(<some conditions>) {
*param2 = calloc(<some memory>);
param1->memberVar = *param2;
}

}

However, since you assign the allocation to param1->memberVar
(which I assume is an int*), it makes more sense to do this:

void FuncA(.....)
{
struct somekind param1;

FuncB(&param1);
<do something>
if(param1.memberVar!=NULL) {
free(param1.memberVar);
param1.memberVar=NULL;
}

}

void FuncB(struct sometype *param1)
{
if(<some conditions>) {
/* before doing this, you should worry
* about whether memberVar already points somewhere
*/
param1->memberVar = calloc(<some memory>);
}
else {
param1->memberVar = NULL;
}

}

Fred,
param1->memberVar is an int *; and what you've said is absolutely
correct; in fact that was the way I wanted to implement it at first.
However, the members of param1 are initialized by FuncA by several
calls to library functions and so memberVar may already be non-NULL.
Also, in the actual program FuncB take 2 structure pointer parameters
and 2 int* parameters; it then attempts to cross fill any missing
information in both structures using a set of rules. So if I was to
implement it the way you suggested FuncA would need to remember
whether the memberVar pointers in the 2 structures were initialized
before calling FuncB. I figured this was a better way to do it since
FuncB could do all that by itself.

Ashish.
 

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

Top