When it will be freed?

Discussion in 'C Programming' started by tfelb, Jan 20, 2009.

  1. tfelb

    tfelb Guest

    Hi group!

    There are many string functions out there and many use malloc/calloc
    mechanisms /but/ they aren't freed before the function returns? When
    it will be freed? Because if I use strdup many times the function
    malloc's every time more space from the heap or is my thesis wrong?

    I saw many implementations of strdup and they all are similar

    char *strdup(char *s1)
    {

    char *newString;
    newString = (char *)malloc(strlen(s1) + 1); /* I know casting
    malloc isn't necessary
    strcpy(newString,s1);
    return newString; /* no freeing */
    }

    Thank you!

    Tom F.
    tfelb, Jan 20, 2009
    #1
    1. Advertising

  2. tfelb <> writes:

    > There are many string functions out there and many use malloc/calloc
    > mechanisms /but/ they aren't freed before the function returns? When
    > it will be freed? Because if I use strdup many times the function
    > malloc's every time more space from the heap or is my thesis wrong?


    That's right. The program using the function need to free the
    space when it know there is not more use for it. Only the programmer
    knows when this is.

    > I saw many implementations of strdup and they all are similar
    >
    > char *strdup(char *s1)
    > {
    >
    > char *newString;
    > newString = (char *)malloc(strlen(s1) + 1); /* I know casting
    > malloc isn't necessary
    > strcpy(newString,s1);
    > return newString; /* no freeing */
    > }


    const char * would be a better type for the parameter and something
    other then undefined behaviour should happen when malloc returns NULL.

    --
    Ben.
    Ben Bacarisse, Jan 20, 2009
    #2
    1. Advertising

  3. tfelb

    Rafael Guest

    tfelb escreveu:
    > Hi group!
    >
    > There are many string functions out there and many use malloc/calloc
    > mechanisms /but/ they aren't freed before the function returns? When
    > it will be freed? Because if I use strdup many times the function
    > malloc's every time more space from the heap or is my thesis wrong?
    >
    > I saw many implementations of strdup and they all are similar
    >
    > char *strdup(char *s1)
    > {
    >
    > char *newString;
    > newString = (char *)malloc(strlen(s1) + 1); /* I know casting
    > malloc isn't necessary
    > strcpy(newString,s1);
    > return newString; /* no freeing */
    > }


    Memory free'd on caller side, maybe? You are receiving a pointer to
    char... you can just do

    char *whatever = strdup(whatothereverchar);

    if(whatever)
    free(whatever);


    Rafael
    Rafael, Jan 20, 2009
    #3
  4. tfelb

    Richard Guest

    tfelb <> writes:

    > Hi group!
    >
    > There are many string functions out there and many use malloc/calloc
    > mechanisms /but/ they aren't freed before the function returns? When
    > it will be freed? Because if I use strdup many times the function
    > malloc's every time more space from the heap or is my thesis wrong?


    It is your responsible to free them.

    >
    > I saw many implementations of strdup and they all are similar
    >
    > char *strdup(char *s1)
    > {
    >
    > char *newString;
    > newString = (char *)malloc(strlen(s1) + 1); /* I know casting
    > malloc isn't necessary


    And is bad. Apparently but I never saw any side affects. The "danger" is
    a c.l.c thing but why tempt fate? Remove the cast.

    > strcpy(newString,s1);
    > return newString; /* no freeing */
    > }



    Something (untested) like this is fine IMO.

    char * strdup(char *s){
    return strcpy(malloc(strlen(s)+1),s);
    }

    Perfect. Nice crash if you run out of malloc space too. But if you do
    then the system is hosed anyway.....
    Richard, Jan 20, 2009
    #4
  5. Rafael wrote:
    > tfelb escreveu:
    >> Hi group!
    >>
    >> There are many string functions out there and many use malloc/calloc
    >> mechanisms /but/ they aren't freed before the function returns? When
    >> it will be freed? Because if I use strdup many times the function
    >> malloc's every time more space from the heap or is my thesis wrong?
    >>
    >> I saw many implementations of strdup and they all are similar
    >>
    >> char *strdup(char *s1)
    >> {
    >>
    >> char *newString;
    >> newString = (char *)malloc(strlen(s1) + 1); /* I know casting
    >> malloc isn't necessary
    >> strcpy(newString,s1);
    >> return newString; /* no freeing */
    >> }

    >
    > Memory free'd on caller side, maybe? You are receiving a pointer to
    > char... you can just do
    >
    > char *whatever = strdup(whatothereverchar);
    >
    > if(whatever)
    > free(whatever);


    As free(NULL); is perfectly legal (and a NOP), you can even drop the if
    (whatever) and save the cycles

    Bye, Jojo
    Joachim Schmitz, Jan 20, 2009
    #5
  6. On Jan 20, 10:44 am, tfelb <> wrote:
    > There are many string functions out there and many use malloc/

    calloc
    > mechanisms /but/ they aren't freed before the function returns? When
    > it will be freed? Because if I use strdup many times the function
    > malloc's every time more space from the heap or is my thesis wrong?
    >
    > I saw many implementations of strdup and they all are similar
    >
    > char *strdup(char *s1)
    > {
    >
    >    char *newString;
    >    newString = (char *)malloc(strlen(s1) + 1); /* I know casting
    > malloc isn't necessary
    >    strcpy(newString,s1);
    >    return newString;  /* no freeing */
    >
    > }


    strdup is non-standard but widely used. Accessing your system
    documentation will probably tell you something like this seen on
    linux:

    The strdup() function returns a pointer to a new string which
    is a duplicate of the string s. Memory for the new string is obtained
    with malloc(3), and can be freed with free(3).

    i.e. when you are done with the string returned, you should call free
    on the returned pointer or you will leak memory.

    The above is a subpar implementation of strdup for a number of reasons
    not relevant to your question, btw. Some things that might be done
    differently:

    1) name is in implementation namespace (strx), but whatever, it is a
    very common
    extension, I expect any future standard function named "strdup"
    would have
    identical signature and semantics to the widely available one.
    So no big
    problem presumably.
    2) Argument should really be const char*.
    3) Doesn't check argument for NULL
    4) Doesn't check malloc for success (at least on my system is
    documented to set
    errno to ENOMEM on malloc failure)
    5) Casts malloc (which you noted, discussed to death, so whatever)
    6) I'd rather use memcpy (since the strlen is already measured once in
    fn)

    Some of the above are just design decisions I guess...

    -David
    David Resnick, Jan 20, 2009
    #6
  7. tfelb

    tfelb Guest

    On 20 Jan., 17:12, David Resnick <> wrote:
    > On Jan 20, 10:44 am, tfelb <> wrote:
    >  > There are many string functions out there and many use malloc/
    > calloc
    >
    >
    >
    >
    >
    > > mechanisms /but/ they aren't freed before the function returns? When
    > > it will be freed? Because if I use strdup many times the function
    > > malloc's every time more space from the heap or is my thesis wrong?

    >
    > > I saw many implementations of strdup and they all are similar

    >
    > > char *strdup(char *s1)
    > > {

    >
    > >    char *newString;
    > >    newString = (char *)malloc(strlen(s1) + 1); /* I know casting
    > > malloc isn't necessary
    > >    strcpy(newString,s1);
    > >    return newString;  /* no freeing */

    >
    > > }

    >
    > strdup is non-standard but widely used.  Accessing your system
    > documentation will probably tell you something like this seen on
    > linux:
    >
    >        The strdup() function returns a pointer to a new string which
    > is a duplicate of the string s.  Memory for the new string is obtained
    > with malloc(3), and can  be  freed with free(3).
    >
    > i.e. when you are done with the string returned, you should call free
    > on the returned pointer or you will leak memory.
    >
    > The above is a subpar implementation of strdup for a number of reasons
    > not relevant to your question, btw.  Some things that might be done
    > differently:
    >
    > 1) name is in implementation namespace (strx), but whatever, it is a
    > very common
    >       extension, I expect any future standard function named "strdup"
    > would have
    >       identical signature and semantics to the widely available one..
    > So no big
    >       problem presumably.
    > 2) Argument should really be const char*.
    > 3) Doesn't check argument for NULL
    > 4) Doesn't check malloc for success (at least on my system is
    > documented to set
    >          errno to ENOMEM on malloc failure)
    > 5) Casts malloc (which you noted, discussed to death, so whatever)
    > 6) I'd rather use memcpy (since the strlen is already measured once in
    > fn)
    >
    > Some of the above are just design decisions I guess...
    >
    > -David- Zitierten Text ausblenden -
    >
    > - Zitierten Text anzeigen -


    Thank you! This was a test function with no built-in checks.
    tfelb, Jan 20, 2009
    #7
  8. Gordon Burditt wrote:
    >> Because if I use strdup many times the function
    >> malloc's every time more space from the heap or is my thesis wrong?

    >
    > strdup() (not a standard C function) wouldn't be very useful if it
    > kept re-using the same memory to store strings.


    Exactly. One of the common uses for strdup() is to "fix" functions that
    return a pointer to a static buffer, so if strdup() did the same thing,
    it'd be rather pointless.

    S

    --
    Stephen Sprunk "Stupid people surround themselves with smart
    CCIE #3723 people. Smart people surround themselves with
    K5SSS smart people who disagree with them." --Isaac Jaffe
    Stephen Sprunk, Jan 20, 2009
    #8
  9. tfelb

    Rafael Guest

    Joachim Schmitz escreveu:

    > As free(NULL); is perfectly legal (and a NOP), you can even drop the if
    > (whatever) and save the cycles


    Wouldn't I save a cycle not calling free?

    Rafael
    Rafael, Jan 20, 2009
    #9
  10. In article <gl4uc0$rub$>,
    Rafael <> wrote:

    >> As free(NULL); is perfectly legal (and a NOP), you can even drop the if
    >> (whatever) and save the cycles


    >Wouldn't I save a cycle not calling free?


    Several, but only when strdup() failed, which Is hardly ever going to
    be true.

    Either way, the difference is unlikely to be noticable.

    -- Richard
    --
    Please remember to mention me / in tapes you leave behind.
    Richard Tobin, Jan 20, 2009
    #10
  11. tfelb

    jameskuyper Guest

    Rafael wrote:
    > Joachim Schmitz escreveu:
    >
    > > As free(NULL); is perfectly legal (and a NOP), you can even drop the if
    > > (whatever) and save the cycles

    >
    > Wouldn't I save a cycle not calling free?


    That depends upon what your code is doing. In typical contexts, I
    write

    p = malloc(*p);
    if(p)
    {
    // Code which uses p

    free(p);
    }

    In such contexts, I already need the if() just to protect the other
    code which uses p; putting the free() inside the if() block rather
    than outside of it saves an unnecessary function call, at no extra
    cost.

    However, in this case you just have

    if(whatever)
    free(whatever);

    That performs one extra comparison every time the if() statement is
    executed; it saves you one function call every time that 'whatever' is
    a null pointer. Whether or not that gives you a net speed-up depends
    upon the how much time the comparison takes, compared to the overhead
    of a function call, but it also depends upon how often 'whatever' is
    null. For most of the programs I write, a malloc() failure usually
    requires premature termination of the program, so if malloc() failures
    were common, they would indicate poor program design - the work to be
    done needs to be broken down into pieces small enough to avoid putting
    so much strain on the available memory. As a result, I would seldom
    write such code. However, there might be contexts where non-fatal
    malloc() failures are more common than in my code.
    jameskuyper, Jan 20, 2009
    #11
  12. Rafael wrote:
    > Joachim Schmitz escreveu:
    >
    >> As free(NULL); is perfectly legal (and a NOP), you can even drop the
    >> if (whatever) and save the cycles

    >
    > Wouldn't I save a cycle not calling free?


    Only in the case where the malloc() inside strdup() failed, which should
    be rare enough to not worry about. However, you will usually be
    checking the return value of strdup() to avoid passing a NULL to other
    functions that aren't defined to handle it properly, so the free()
    probably won't end up in the execution path anyways.

    S

    --
    Stephen Sprunk "Stupid people surround themselves with smart
    CCIE #3723 people. Smart people surround themselves with
    K5SSS smart people who disagree with them." --Isaac Jaffe
    Stephen Sprunk, Jan 20, 2009
    #12
  13. tfelb

    Rafael Guest

    Richard Tobin escreveu:
    > In article <gl4uc0$rub$>,
    > Rafael <> wrote:
    >
    >>> As free(NULL); is perfectly legal (and a NOP), you can even drop the if
    >>> (whatever) and save the cycles

    >
    >> Wouldn't I save a cycle not calling free?

    >
    > Several, but only when strdup() failed, which Is hardly ever going to
    > be true.
    >
    > Either way, the difference is unlikely to be noticable.


    Your'e right.... I'll better find out if strdup failed on call. If yes,
    just take another course.

    char *whatever;

    int docomplain()
    {
    printf("Problems\n");
    return EXIT_FAILURE;
    }

    if( (whatever = strdup(whatothereverchar))==NULL)
    return docomplain();

    free(whatever);
    Rafael, Jan 20, 2009
    #13
  14. tfelb

    Rafael Guest

    jameskuyper escreveu:

    > That depends upon what your code is doing. In typical contexts, I
    > write


    I've figured that... take a look on my reply to Richard Tobin. Its kind
    of the same, but not being the same. ...?


    Rafael
    Rafael, Jan 20, 2009
    #14
  15. tfelb

    Rafael Guest

    Stephen Sprunk escreveu:
    > Rafael wrote:
    >> Joachim Schmitz escreveu:
    >>
    >>> As free(NULL); is perfectly legal (and a NOP), you can even drop the
    >>> if (whatever) and save the cycles

    >>
    >> Wouldn't I save a cycle not calling free?

    >
    > Only in the case where the malloc() inside strdup() failed, which should
    > be rare enough to not worry about. However, you will usually be
    > checking the return value of strdup() to avoid passing a NULL to other
    > functions that aren't defined to handle it properly, so the free()
    > probably won't end up in the execution path anyways.
    >
    > S
    >

    I really should read all feedbacks before post anything.


    I've figured that... take a look on my reply to Richard Tobin. Its kind
    of the same, but not being the same. ...?


    Rafael
    Rafael, Jan 20, 2009
    #15
  16. tfelb

    jameskuyper Guest

    Rafael wrote:
    > jameskuyper escreveu:
    >
    > > That depends upon what your code is doing. In typical contexts, I
    > > write

    >
    > I've figured that... take a look on my reply to Richard Tobin. Its kind
    > of the same, but not being the same. ...?


    The code you wrote is only fragments that don't work together. It
    includes a declaration of a function, which must occur at file scope,
    with executable statements which could only occur in block scope. It
    also has a declaration of an object that could legally occur at either
    file scope or block scope, but would probably constitute poor design
    at file scope.
    It allocates memory for a copy of a string, and then does nothing with
    the copy before free()ing that memory. I presume that these fragments
    are meant to exist in a larger context where they all make sense
    together, but it would be easier to judge whether or not they're
    correct if you would show them in a simplified version of that
    context.
    jameskuyper, Jan 20, 2009
    #16
  17. tfelb

    Rafael Guest

    jameskuyper escreveu:
    > The code you wrote is only fragments that don't work together.


    Yeah... even to myself, that's confusing.

    > correct if you would show them in a simplified version of that
    > context.


    Not willing to be a complete implementation (since even strdup
    declaration is not here, and no includes, but now one can figure, and I
    can train my lazyness neural network):

    int docomplain()
    {
    printf("Problems\n");
    return EXIT_FAILURE;
    }

    int main(int argc, char **argv)
    {
    char *whatever;

    if( (whatever = strdup(whatothereverchar))==NULL)
    return docomplain();

    /*handle whatever*/

    free(whatever);

    return EXIT_SUCCESS;
    }


    Rafael
    Rafael, Jan 20, 2009
    #17
  18. tfelb

    jameskuyper Guest

    Rafael wrote:
    > jameskuyper escreveu:
    > > The code you wrote is only fragments that don't work together.

    >
    > Yeah... even to myself, that's confusing.
    >
    > > correct if you would show them in a simplified version of that
    > > context.

    >
    > Not willing to be a complete implementation (since even strdup
    > declaration is not here, and no includes, but now one can figure, and I
    > can train my lazyness neural network):
    >
    > int docomplain()
    > {
    > printf("Problems\n");
    > return EXIT_FAILURE;
    > }
    >
    > int main(int argc, char **argv)
    > {
    > char *whatever;
    >
    > if( (whatever = strdup(whatothereverchar))==NULL)


    I'd re-write that as

    char *whatever = strdup(whatothereverchar);
    if(whatever == NULL)

    but that's just a matter of style.

    > return docomplain();
    > /*handle whatever*/
    >
    > free(whatever);
    >
    > return EXIT_SUCCESS;
    > }


    Structured programming purists would object to the early return from
    main(). I'm not such a purist, though I recognize that there's some
    validity in their objections to such code.
    jameskuyper, Jan 20, 2009
    #18
  19. tfelb

    Rafael Guest

    jameskuyper escreveu:

    >> int docomplain()
    >> {
    >> printf("Problems\n");
    >> return EXIT_FAILURE;
    >> }
    >>
    >> int main(int argc, char **argv)
    >> {
    >> char *whatever;
    >>
    >> if( (whatever = strdup(whatothereverchar))==NULL)
    >> return docomplain();
    >> /*handle whatever*/
    >>
    >> free(whatever);
    >>
    >> return EXIT_SUCCESS;
    >> }

    >
    > Structured programming purists would object to the early return from
    > main(). I'm not such a purist, though I recognize that there's some
    > validity in their objections to such code.


    Sorry, but I don't think I get the "early return" meaning...
    What should I do? Write more fake code?

    I didn't even told you where whatothereverchar comes from... :)

    Rafael
    Rafael, Jan 20, 2009
    #19
  20. Rafael wrote:
    > jameskuyper escreveu:
    >> Structured programming purists would object to the early return from
    >> main(). I'm not such a purist, though I recognize that there's some
    >> validity in their objections to such code.

    >
    > Sorry, but I don't think I get the "early return" meaning...
    > What should I do? Write more fake code?


    Some programmers do not like the idea of multiple return points from a
    function; they want all code paths to reach a single return point at the
    end of the function. They often extend the same logic to main(),
    basically banning the use of exit() and requiring all functions to
    return so that (the first instance of) main() returns from a single point.

    While there are some advantages to having a single return point, more
    pragmatic programmers believe that complex code is often easier to
    understand with multiple return (or exit()) points. This is not unlike
    the debate about "goto"; avoiding it is a good idea in general, but
    there are times it's the best tool for the job.

    S

    --
    Stephen Sprunk "Stupid people surround themselves with smart
    CCIE #3723 people. Smart people surround themselves with
    K5SSS smart people who disagree with them." --Isaac Jaffe
    Stephen Sprunk, Jan 20, 2009
    #20
    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. dg
    Replies:
    0
    Views:
    320
  2. jimjim
    Replies:
    28
    Views:
    857
    Michael Wojcik
    Apr 14, 2004
  3. David Scarlett

    Just how delicate are freed pointers?

    David Scarlett, May 16, 2004, in forum: C Programming
    Replies:
    73
    Views:
    1,254
    Dan Pop
    May 21, 2004
  4. ravi
    Replies:
    72
    Views:
    1,442
    RCollins
    Sep 14, 2004
  5. Replies:
    14
    Views:
    644
Loading...

Share This Page