freeing of char**

Discussion in 'C Programming' started by gregg, Jan 22, 2004.

  1. gregg

    gregg Guest

    Hello all,


    I have a char **, which points to a number of strings (char*).
    When comes the moment to free it, i have to free all the (char*) inside.
    Yet when i do this:

    int i;

    for ( i=0; *(myChar+i) != NULL; i++ )
    free (*(myChar+i)); /* to free the (char*) inside
    free(myChar);


    well, on execution the system says 'junk pointer, too low to make sense'
    (and the pointers aren't freed)

    of course, when i write (*(myChar+i) = NULL), it's all okay
    (except the memory hasn't been freed ?!)

    so how should i free the (char**) to make it work, and also be clean ?

    thx
    gregg
     
    gregg, Jan 22, 2004
    #1
    1. Advertising

  2. gregg

    Dan Pop Guest

    In <40100736$0$17108$> gregg <> writes:

    >I have a char **, which points to a number of strings (char*).
    >When comes the moment to free it, i have to free all the (char*) inside.
    >Yet when i do this:
    >
    >int i;
    >
    >for ( i=0; *(myChar+i) != NULL; i++ )
    > free (*(myChar+i)); /* to free the (char*) inside */
    >free(myChar);
    >
    >
    >well, on execution the system says 'junk pointer, too low to make sense'
    >(and the pointers aren't freed)


    Are you sure that *(myChar+i) (usually written myChar) has been
    initialised with a malloc (or friends) call? Are you sure that your
    array of pointers is terminated by a null pointer?

    Only pointer values obtained from malloc and friends need to be freed.
    It is a major mistake to free any other pointer values.

    So, without seeing how myChar and myChar have been initialised, there
    is no way to telling what you're doing wrong. This is an initialisation
    scenario compatible with your freeing code (error checking omitted for
    brevity):

    char **myChar = malloc(10 * sizeof *myChar);
    for (i = 0; i < 3; i++) myChar = malloc(25);
    myChar[3] = NULL;

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Jan 22, 2004
    #2
    1. Advertising

  3. gregg

    CBFalconer Guest

    gregg wrote:
    >
    > I have a char **, which points to a number of strings (char*).
    > When comes the moment to free it, i have to free all the (char*)
    > inside. Yet when i do this:
    >
    > int i;
    >
    > for ( i=0; *(myChar+i) != NULL; i++ )
    > free (*(myChar+i)); /* to free the (char*) inside
    > free(myChar);
    >
    > well, on execution the system says 'junk pointer, too low to
    > make sense' (and the pointers aren't freed)
    >
    > of course, when i write (*(myChar+i) = NULL), it's all okay
    > (except the memory hasn't been freed ?!)
    >
    > so how should i free the (char**) to make it work, and also
    > be clean ?


    You should post complete compilable programs, cut to the minimum
    from the original, for questions like this. Your description is
    missing the essentials, i.e. how was myChar declared and
    initialized, and how was *myChar initialized.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Jan 22, 2004
    #3
  4. gregg

    Mike Wahler Guest

    "gregg" <> wrote in message
    news:40100736$0$17108$...
    > Hello all,
    >
    >
    > I have a char **, which points to a number of strings (char*).
    > When comes the moment to free it, i have to free all the (char*) inside.
    > Yet when i do this:
    >
    > int i;
    >
    > for ( i=0; *(myChar+i) != NULL; i++ )
    > free (*(myChar+i)); /* to free the (char*) inside
    > free(myChar);
    >
    >
    > well, on execution the system says 'junk pointer, too low to make sense'
    > (and the pointers aren't freed)
    >
    > of course, when i write (*(myChar+i) = NULL), it's all okay
    > (except the memory hasn't been freed ?!)
    >
    > so how should i free the (char**) to make it work, and also be clean ?


    Regardless of the types of objects, only 'free()' what memory
    you 'malloc()' or 'realloc()'. Your code snipped doesn't show
    whether you've done any allocations or not.

    -Mike
     
    Mike Wahler, Jan 22, 2004
    #4
  5. gregg <> spoke thus:


    > for ( i=0; *(myChar+i) != NULL; i++ )


    Nice try, but no. First of all, just because a pointer isn't NULL
    doesn't mean you should attempt to free it (you may not have even
    malloc()'ed it!). Secondly, you seem to be treating your char** like
    a char* - i.e., that it is NULL terminated. If it were, you'd be
    fine. However, unless you've made specific arrangements (i.e., myChar
    points to enough space for a pointer to NULL in addition to all the
    char pointers), this will almost assuredly fail. It's a much better
    plan to just know how many character pointers you allocated, and then
    free() exactly that many.

    > free (*(myChar+i)); /* to free the (char*) inside


    Why not just free( myChar ); ? It looks cleaner and accomplishes
    the same thing.

    > of course, when i write (*(myChar+i) = NULL), it's all okay
    > (except the memory hasn't been freed ?!)


    Quite correct - setting a pointer to NULL in no way frees any memory
    it might have been pointing at.

    > so how should i free the (char**) to make it work, and also be clean ?


    Keep track of how many you have (say j):

    for( i=0 ; i<j ; i++)
    free( myChar );
    free( myChar );

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Jan 22, 2004
    #5
  6. gregg

    gregg Guest

    CBFalconer wrote:

    > You should post complete compilable programs, cut to the minimum
    > from the original, for questions like this. Your description is
    > missing the essentials, i.e. how was myChar declared and
    > initialized, and how was *myChar initialized.
    >


    This is the function:

    char ** resetResults (char ** res) {

    int i;

    if ( res != NULL ) { /* if not NULL, has to be freed */
    for ( i=0; *(res+i) != NULL; i++ ) {
    free(*(res+i));
    }
    free(res);
    }
    /* new allocation, shall contains one char* to NULL */
    res=(char**)realloc(NULL, sizeof(char*));

    if ( res != NULL ) return res;
    else exit(RESULT_ALLOC_PB);
    }


    The purpose is to stock an indefinite number of strings (ie. char*).
    The end is marked with NULL pointer (a bit like **argv).

    Now comes a moment when a new search is to be made: thus the strings
    contained in char** must be freed, and a new char** containing one NULL
    pointer (meaning it is empty) has to be created.

    That's my point: i want to free all strings, then the char** which
    contained them. and then create a fresh new one.
    (To keep memory clean, i don't want to use *(res+i)= NULL, which works,
    but does not free memory !)
     
    gregg, Jan 22, 2004
    #6
  7. gregg

    Eric Sosman Guest

    gregg wrote:
    >
    > CBFalconer wrote:
    >
    > > You should post complete compilable programs, cut to the minimum
    > > from the original, for questions like this. Your description is
    > > missing the essentials, i.e. how was myChar declared and
    > > initialized, and how was *myChar initialized.
    > >

    >
    > This is the function:
    >
    > char ** resetResults (char ** res) {
    >
    > int i;
    >
    > if ( res != NULL ) { /* if not NULL, has to be freed */
    > for ( i=0; *(res+i) != NULL; i++ ) {
    > free(*(res+i));
    > }
    > free(res);
    > }
    > /* new allocation, shall contains one char* to NULL */
    > res=(char**)realloc(NULL, sizeof(char*));


    Add: *res = NULL;

    > if ( res != NULL ) return res;
    > else exit(RESULT_ALLOC_PB);
    > }


    --
     
    Eric Sosman, Jan 22, 2004
    #7
  8. gregg

    Eric Sosman Guest

    Eric Sosman wrote:
    >
    > gregg wrote:
    > >
    > > CBFalconer wrote:
    > >
    > > > You should post complete compilable programs, cut to the minimum
    > > > from the original, for questions like this. Your description is
    > > > missing the essentials, i.e. how was myChar declared and
    > > > initialized, and how was *myChar initialized.
    > > >

    > >
    > > This is the function:
    > >
    > > char ** resetResults (char ** res) {
    > >
    > > int i;
    > >
    > > if ( res != NULL ) { /* if not NULL, has to be freed */
    > > for ( i=0; *(res+i) != NULL; i++ ) {
    > > free(*(res+i));
    > > }
    > > free(res);
    > > }
    > > /* new allocation, shall contains one char* to NULL */
    > > res=(char**)realloc(NULL, sizeof(char*));

    >
    > Add: *res = NULL;
    >
    > > if ( res != NULL ) return res;
    > > else exit(RESULT_ALLOC_PB);
    > > }


    Ah, yes, well, what I *really* meant, of COURSE,
    was add the assignment after checking that `res' itself
    is non-NULL. (Harrumph.) While you're at it, replace
    the peculiar realloc() with the simpler malloc() and
    clean things up a trifle:

    /* new allocation, shall contains one char* to NULL */
    res = malloc(sizeof *res);
    if (res != NULL) {
    *res = NULL;
    return res;
    }
    exit (RESULT_ALLOC_PB);

    --
     
    Eric Sosman, Jan 22, 2004
    #8
  9. gregg

    CBFalconer Guest

    gregg wrote:
    > CBFalconer wrote:
    >
    > > You should post complete compilable programs, cut to the minimum
    > > from the original, for questions like this. Your description is
    > > missing the essentials, i.e. how was myChar declared and
    > > initialized, and how was *myChar initialized.

    >
    > This is the function:
    >
    > char ** resetResults (char ** res) {
    >
    > int i;
    >
    > if ( res != NULL ) { /* if not NULL, has to be freed */
    > for ( i=0; *(res+i) != NULL; i++ ) {
    > free(*(res+i));
    > }
    > free(res);
    > }
    > /* new allocation, shall contains one char* to NULL */
    > res=(char**)realloc(NULL, sizeof(char*));
    >
    > if ( res != NULL ) return res;
    > else exit(RESULT_ALLOC_PB);
    > }
    >
    > The purpose is to stock an indefinite number of strings (ie. char*).
    > The end is marked with NULL pointer (a bit like **argv).


    That is still not a complete compilable program. I, and many
    others, will not bother to look at it. Dan and Mike have given
    you good advice.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Jan 23, 2004
    #9
    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. wwj
    Replies:
    7
    Views:
    574
  2. wwj
    Replies:
    24
    Views:
    2,544
    Mike Wahler
    Nov 7, 2003
  3. Ben Pfaff
    Replies:
    5
    Views:
    490
    Tristan Miller
    Jan 17, 2004
  4. Steffen Fiksdal

    void*, char*, unsigned char*, signed char*

    Steffen Fiksdal, May 8, 2005, in forum: C Programming
    Replies:
    1
    Views:
    605
    Jack Klein
    May 9, 2005
  5. lovecreatesbeauty
    Replies:
    1
    Views:
    1,096
    Ian Collins
    May 9, 2006
Loading...

Share This Page