How to handle pointers inside of a function ?

Discussion in 'C Programming' started by George Marshall, Oct 13, 2003.

  1. Hi all, my question is what should I do with a pointer
    to be used inside a function ?

    The following function should take a pointer to a null
    terminated array of chars, do something with it, and
    write to the other pointer (*dest).

    Should I check if the *dest pointer is NULL or not
    before writing to it ? Should I realloc it before
    I write to it ? Should I free it if != NULL and
    then allocate it again ?

    Thanks.

    /* Example function */
    int str_do_something ( const char *src, char *dest)
    {
    if (src == NULL)
    return 0;

    do_something_to_str(src);

    /* What is good practice to do with the dest pointer here ?*/
    /* free before malloc ? realloc ? check if != NULL ? */
    dest = malloc (strlen(src));
    if (dest == NULL)
    return -1;
    strcpy (dest,src);
    return 0;
    }
    George Marshall, Oct 13, 2003
    #1
    1. Advertising

  2. George Marshall

    Allan Bruce Guest

    "George Marshall" <> wrote in message
    news:_rtib.33215$...
    > Hi all, my question is what should I do with a pointer
    > to be used inside a function ?
    >
    > The following function should take a pointer to a null
    > terminated array of chars, do something with it, and
    > write to the other pointer (*dest).
    >
    > Should I check if the *dest pointer is NULL or not
    > before writing to it ? Should I realloc it before
    > I write to it ? Should I free it if != NULL and
    > then allocate it again ?
    >
    > Thanks.
    >
    > /* Example function */
    > int str_do_something ( const char *src, char *dest)
    > {
    > if (src == NULL)
    > return 0;
    >
    > do_something_to_str(src);
    >
    > /* What is good practice to do with the dest pointer here ?*/
    > /* free before malloc ? realloc ? check if != NULL ? */
    > dest = malloc (strlen(src));
    > if (dest == NULL)
    > return -1;
    > strcpy (dest,src);
    > return 0;
    > }
    >


    I usually design the function to take a garbage pointer in and initialise it
    within the function.
    In this case, I would use the return value of 0 for an error (either, the
    src pointer is garbage or the memory allocation fails), and would return the
    result from strcpy or perhaps the amount of memory allocated to the new
    pointer if you are doing some other function.
    HTH
    Allan
    Allan Bruce, Oct 13, 2003
    #2
    1. Advertising

  3. George Marshall

    T.M. Sommers Guest

    George Marshall wrote:
    > Hi all, my question is what should I do with a pointer
    > to be used inside a function ?
    >
    > The following function should take a pointer to a null
    > terminated array of chars, do something with it, and
    > write to the other pointer (*dest).
    >
    > Should I check if the *dest pointer is NULL or not
    > before writing to it ? Should I realloc it before
    > I write to it ? Should I free it if != NULL and
    > then allocate it again ?


    It's up to you; just make sure you document it so that users of your
    function (including you next week) know how it works. For example,
    users need to know that the function as implemented below allocates
    memory, so that they, the users, have to free it later.

    > /* Example function */
    > int str_do_something ( const char *src, char *dest)


    int str_do_something ( const char *src, char **dest)

    Since you are modifying dest, you need to pass in a pointer to it. Or
    you could have the function return a char *.

    > {
    > if (src == NULL)
    > return 0;
    >
    > do_something_to_str(src);
    >
    > /* What is good practice to do with the dest pointer here ?*/
    > /* free before malloc ? realloc ? check if != NULL ? */
    > dest = malloc (strlen(src));


    *dest = malloc (strlen(src) + 1);

    Don't forget the terminating NULL.

    > if (dest == NULL)


    if (*dest == NULL)

    > return -1;
    > strcpy (dest,src);


    strcpy (*dest,src);

    > return 0;
    > }
    >


    It also might be better to do_something to the new string, not the
    original. It is generally best to have a function do one thing
    (return modified copy of string) rather than two (modify string,
    return copy of modified string).

    char *str_do_something ( const char *src )
    {
    char *dest = NULL;
    if ( src ) {
    if ( (*dest = malloc (strlen(src) + 1)) ) {
    strcpy(*dest, src);
    do_something_to_str(dest);
    }
    }
    return dest;
    }
    T.M. Sommers, Oct 13, 2003
    #3
  4. George Marshall

    Allan Bruce Guest

    "Allan Bruce" <> wrote in message
    news:bmdufi$mde$2surf.net...
    >
    > "George Marshall" <> wrote in message
    > news:_rtib.33215$...
    > > Hi all, my question is what should I do with a pointer
    > > to be used inside a function ?
    > >
    > > The following function should take a pointer to a null
    > > terminated array of chars, do something with it, and
    > > write to the other pointer (*dest).
    > >
    > > Should I check if the *dest pointer is NULL or not
    > > before writing to it ? Should I realloc it before
    > > I write to it ? Should I free it if != NULL and
    > > then allocate it again ?
    > >
    > > Thanks.
    > >
    > > /* Example function */
    > > int str_do_something ( const char *src, char *dest)
    > > {
    > > if (src == NULL)
    > > return 0;
    > >
    > > do_something_to_str(src);
    > >
    > > /* What is good practice to do with the dest pointer here ?*/
    > > /* free before malloc ? realloc ? check if != NULL ? */
    > > dest = malloc (strlen(src));
    > > if (dest == NULL)
    > > return -1;
    > > strcpy (dest,src);
    > > return 0;
    > > }
    > >

    >
    > I usually design the function to take a garbage pointer in and initialise

    it
    > within the function.
    > In this case, I would use the return value of 0 for an error (either, the
    > src pointer is garbage or the memory allocation fails), and would return

    the
    > result from strcpy or perhaps the amount of memory allocated to the new
    > pointer if you are doing some other function.
    > HTH
    > Allan
    >
    >


    Since I was bored, I have written a sample program that I would use for
    doing what you wish. Ignore it, use it or rape it, up to you ;-)




    #include "stdlib.h"
    #include "stdio.h"
    #include "string.h"

    int strSomething(const char *xiSrc, char **xoDst);

    int main (void)
    {
    char *src = "Some Text Here";
    char *dst = NULL;
    int memAllocd;

    if ((memAllocd = strSomething(src, &dst)) == 0)
    printf("Error Allocating Memory\n");
    else
    printf("Memory Allocated: %d Bytes\nContents: %s\n", memAllocd, dst);

    /* Free the memory allocated */
    if (dst)
    free(dst);

    return 0;
    }

    /************************************************
    * Name: strSomething
    * Desription: xxx
    ************************************************/
    int strSomething(const char *xiSrc, char **xoDst)
    {
    /* I use xiXXX for pointers that are valid coming into a function
    and should not be altered. xoXXX for pointers which are garbage
    and should be allocated and alterd. */
    int lMemAllocd;

    if (xiSrc == NULL)
    return 0;

    /* Allocate enough memory for the string and NULL terminator */
    if ((*xoDst = malloc(lMemAllocd = strlen(xiSrc)+1)) == NULL)
    return 0;

    /* Do something to the string */
    strcpy(*xoDst, xiSrc);

    return lMemAllocd;
    }
    Allan Bruce, Oct 13, 2003
    #4
  5. George Marshall <> wrote:

    >Hi all, my question is what should I do with a pointer
    >to be used inside a function ?
    >
    >The following function should take a pointer to a null
    >terminated array of chars, do something with it, and
    >write to the other pointer (*dest).
    >
    >Should I check if the *dest pointer is NULL or not
    >before writing to it ?


    If you are writing to memory through a pointer you should /always/ check
    it's != NULL (unless you already know for sure it's a valid pointer).

    >Should I realloc it before
    >I write to it ? Should I free it if != NULL and
    >then allocate it again ?


    If you do so in the example you provide below, the result of both
    strategies is nothing more but a memory leak, as the caller of the
    function will never be able to retrieve the new pointer.

    Additionally, (re)allocation will only be possible if dest is not
    declared as an array.

    >Thanks.
    >
    >/* Example function */
    >int str_do_something ( const char *src, char *dest)
    >{
    > if (src == NULL)
    > return 0;
    >
    > do_something_to_str(src);


    Ouch. You _do_something_to_a_const_char_*_ here, which is presumably not
    what the caller of this function expects to happen.

    > /* What is good practice to do with the dest pointer here ?*/
    > /* free before malloc ? realloc ? check if != NULL ? */
    > dest = malloc (strlen(src));


    Severe error if dest was an array originally!

    > if (dest == NULL)
    > return -1;
    > strcpy (dest,src);


    Booom (read: undefined behaviour)!
    You did not allocate enough memory to hold the copy of src.

    > return 0;
    >}


    How do you expect anybody to access the memory dest currently points to,
    once you lost the only reference to it after your function returned?

    Common practice is to let the caller take care of the memory allocation,
    check for NULL pointers, eventually let the caller supply an additional
    size argument (like in strncpy), and return a pointer to the resulting
    string, like in the following (admittedly silly) example:

    /*--------------8<----------------------------*/

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    char *do_something_to( char *s )
    {
    char *p;

    for ( p = s; *p; p++ )
    if ( *p == 'u' )
    *p = 'x';

    return s;
    }

    char *str_do_something( char *dest, const char *src )
    {
    if ( dest == NULL || src == NULL )
    return NULL;

    strcpy( dest, src );

    return do_something_to( dest );
    }

    int main( void )
    {
    char s[10] = "useless";
    char t[10];

    if ( str_do_something( t, s ) == NULL )
    return EXIT_FAILURE;

    printf( "s: %s\nt: %s\n", s, t );
    return EXIT_SUCCESS;
    }

    /*--------------8<----------------------------*/

    Another possibility is to take only src as argument, allocate dest in
    the function and return it to the caller, much like the (non-standard)
    strdup function available on many implementations.

    HTH

    Regards
    --
    Irrwahn
    ()
    Irrwahn Grausewitz, Oct 13, 2003
    #5
  6. George Marshall

    Ed Morton Guest

    George Marshall wrote:
    > Hi all, my question is what should I do with a pointer
    > to be used inside a function ?
    >
    > The following function should take a pointer to a null
    > terminated array of chars, do something with it, and
    > write to the other pointer (*dest).
    >
    > Should I check if the *dest pointer is NULL or not
    > before writing to it ? Should I realloc it before
    > I write to it ? Should I free it if != NULL and
    > then allocate it again ?


    Just document the interface as requiring *dest to be NULL and test for
    that. Keep it simple. Assuming you want to keep *dest as a parameter,
    I'd write your function as:

    int str_do_something ( const char *src, char **dest)
    {
    int ret = 0;
    if (dest == NULL) {
    ret = -1;
    } else if (*dest != NULL) {
    ret = -2;
    } else if (src != NULL) {
    *dest = malloc (strlen(src) + 1);
    if (*dest == NULL) {
    ret = -3;
    } else {
    (void)strcpy (*dest,src);
    do_something_to_str(*dest);
    }
    }
    return ret;
    }

    Regards,

    Ed.

    > Thanks.
    >
    > /* Example function */
    > int str_do_something ( const char *src, char *dest)
    > {
    > if (src == NULL)
    > return 0;
    >
    > do_something_to_str(src);
    >
    > /* What is good practice to do with the dest pointer here ?*/
    > /* free before malloc ? realloc ? check if != NULL ? */
    > dest = malloc (strlen(src));
    > if (dest == NULL)
    > return -1;
    > strcpy (dest,src);
    > return 0;
    > }
    >
    Ed Morton, Oct 13, 2003
    #6
  7. George Marshall

    Nick Austin Guest

    On Mon, 13 Oct 2003 08:34:02 GMT, George Marshall
    <> wrote:

    >Hi all, my question is what should I do with a pointer
    >to be used inside a function ?
    >
    >The following function should take a pointer to a null
    >terminated array of chars, do something with it, and
    >write to the other pointer (*dest).
    >
    >Should I check if the *dest pointer is NULL or not
    >before writing to it ? Should I realloc it before
    >I write to it ? Should I free it if != NULL and
    >then allocate it again ?
    >
    >Thanks.
    >
    >/* Example function */
    >int str_do_something ( const char *src, char *dest)
    >{
    > if (src == NULL)
    > return 0;
    >
    > do_something_to_str(src);
    >
    > /* What is good practice to do with the dest pointer here ?*/
    > /* free before malloc ? realloc ? check if != NULL ? */
    > dest = malloc (strlen(src));
    > if (dest == NULL)
    > return -1;
    > strcpy (dest,src);
    > return 0;
    >}


    Unless you need to distinguish the reason for failure, i'd make
    the function return a pointer instead:

    char *str_do_something (const char *src)
    {
    char *dest = NULL;

    if (src)
    {
    do_something_to_str (src);

    dest = malloc (strlen (src));
    if (dest)
    strcpy (dest,src);
    }

    return dest;
    }

    Nick.
    Nick Austin, Oct 13, 2003
    #7
  8. George Marshall wrote:
    > Hi all, my question is what should I do with a pointer
    > to be used inside a function ?


    [ snip ] ...

    Thank you all. All right.
    George Marshall, Oct 13, 2003
    #8
    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. Phil
    Replies:
    1
    Views:
    639
    llewelly
    Sep 16, 2003
  2. Peter Goddard

    void pointers & void function pointers

    Peter Goddard, May 16, 2005, in forum: C Programming
    Replies:
    3
    Views:
    505
    Peter Goddard
    May 16, 2005
  3. n2xssvv g02gfr12930

    Smart pointers and member function pointers

    n2xssvv g02gfr12930, Nov 26, 2005, in forum: C++
    Replies:
    3
    Views:
    461
    n2xssvv g02gfr12930
    Nov 27, 2005
  4. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    652
  5. Sur
    Replies:
    4
    Views:
    176
Loading...

Share This Page