Freeing memory allocated by another function

Discussion in 'C Programming' started by Praetorian, Dec 5, 2007.

  1. Praetorian

    Praetorian Guest

    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.
    Praetorian, Dec 5, 2007
    #1
    1. Advertising

  2. Praetorian

    Eric Sosman Guest

    Praetorian wrote:
    > This is actually 2 questions:
    > [...]


    I think it's really just one question. Specifically,
    it's Question 4.8 in the comp.lang.c Frequently Asked
    Questions (FAQ) list

    http://www.c-faq.com/

    --
    Eric Sosman, Dec 5, 2007
    #2
    1. Advertising

  3. On Dec 5, 6:39 pm, Praetorian <> wrote:
    > 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 Bousbouras, Dec 5, 2007
    #3
  4. Praetorian

    Guest

    On Dec 5, 10:39 am, Praetorian <> wrote:
    > 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;
    }
    }

    --
    Fred Kleinschmidt
    , Dec 5, 2007
    #4
  5. Praetorian

    Praetorian Guest

    On Dec 5, 11:46 am, Eric Sosman <> wrote:
    > Praetorian wrote:
    > > This is actually 2 questions:
    > > [...]

    >
    > I think it's really just one question. Specifically,
    > it's Question 4.8 in the comp.lang.c Frequently Asked
    > Questions (FAQ) list
    >
    > http://www.c-faq.com/
    >
    > --
    >


    Exactly what I needed, thanks!

    Ashish.
    Praetorian, Dec 5, 2007
    #5
  6. Praetorian

    Praetorian Guest

    On Dec 5, 11:56 am, Spiros Bousbouras <> wrote:
    > On Dec 5, 6:39 pm, Praetorian <> wrote:
    >
    > > 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.
    Praetorian, Dec 5, 2007
    #6
  7. Praetorian

    Praetorian Guest

    On Dec 5, 12:39 pm, wrote:
    > On Dec 5, 10:39 am, Praetorian <> wrote:
    >
    > > 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;
    > }
    >
    > }
    >
    > --
    > Fred Kleinschmidt


    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.
    Praetorian, Dec 5, 2007
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    5
    Views:
    617
    Matt Wharton
    Dec 9, 2004
  2. Hassan Iqbal
    Replies:
    3
    Views:
    492
    Al Bowers
    Sep 25, 2003
  3. binaya

    freeing allocated memory

    binaya, Oct 19, 2003, in forum: C Programming
    Replies:
    11
    Views:
    594
    James Hu
    Oct 19, 2003
  4. Curley Q.

    freeing allocated memory

    Curley Q., Apr 28, 2004, in forum: C Programming
    Replies:
    7
    Views:
    383
    Sam Dennis
    Apr 30, 2004
  5. Peter
    Replies:
    34
    Views:
    1,943
    Richard Tobin
    Oct 22, 2004
Loading...

Share This Page