Pointer to pointer problem. 
Author Message
 Pointer to pointer problem.

Why doesn't this work.
If I remove the first call to malloc "array = malloc(10 * sizeof *array);"
, it works, but that would be incorrect code.
If I move the first call to malloc to the main function, it also works, and
this would be correct code, right ???
But is it possible to keep the first call to malloc in the function test,
and if yes, how should I do this ???

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

int test(char **array);

int test(char **array)
{
        int i;

        array = malloc(10 * sizeof *array);
        if (array == NULL)
        {
                fprintf(stderr, "Memory allocation failed\n");
                exit(EXIT_FAILURE);
        }

        for (i = 0; i < 10; ++i)
        {      
                array[i] = malloc(10 * sizeof **array);
                if (array[i] == NULL)
                {
                        fprintf(stderr, "Memory allocation failed\n");
                        exit(EXIT_FAILURE);
                }      
                strcpy(array[i], "usarin");
        }      

        printf("in the function 'test':\n");
        for (i = 0; i < 10; ++i)
                printf("array[%d] is: \t\t%s\n", i, array[i]);

        return 0;

Quote:
}

int main(void)
{
        char **result_array;
        int i;

        test(result_array);

        printf("in the function 'main':\n");    
        for (i = 0; i < 10; ++i)
                printf("array[%d] is: \t\t%s\n", i, result_array[i]);

        for (i = 0; i < 10; ++i)
                free(result_array[i]);
        free(result_array);

        return 0;

Quote:
}



Sun, 25 Jul 2004 00:35:23 GMT  
 Pointer to pointer problem.


Quote:
> int test(char **array)
> {
>         int i;

>         array = malloc(10 * sizeof *array);

'array' is local to this function. It will go away when test() ends, leaving
you with nothing to access the allocated storage.

If you wish to change a pointer to a pointer to char within a function, you'll
have to pass a pointer to a pointer to a pointer to char and modify the
dereferenced lvalue. I haven't looked at the rest of your code to see if thats
what you really want to do... think about your problem some more. Triple
indirection is rarely necessary.

-Daniel



Sun, 25 Jul 2004 00:52:28 GMT  
 Pointer to pointer problem.


Quote:



>> int test(char **array)
>> {
>>         int i;

>>         array = malloc(10 * sizeof *array);

> 'array' is local to this function. It will go away when test() ends,
> leaving you with nothing to access the allocated storage.

Hmm... but char **result_array; defined in main() should still be valid.
What am I missing?

--
- Mark A. Odell
- Embedded Firmware Design, Inc.
- http://www.embeddedfw.com



Sun, 25 Jul 2004 01:22:39 GMT  
 Pointer to pointer problem.

Quote:




> >> int test(char **array)
> >> {
> >>         int i;

> >>         array = malloc(10 * sizeof *array);

> > 'array' is local to this function. It will go away when test() ends,
> > leaving you with nothing to access the allocated storage.

> Hmm... but char **result_array; defined in main() should still be valid.
> What am I missing?

You're missing that `*array' is never set.  `array' is a local
variable, so modifying it doesn't affect anything in the caller,
whereas `*array' could be used to set a pointer variable in the
caller if test() were called in an appropriate way.


Sun, 25 Jul 2004 01:25:29 GMT  
 Pointer to pointer problem.

Quote:

> You're missing that `*array' is never set.??`array'?is?a?local
> variable, so modifying it doesn't affect anything in the caller,
> whereas `*array' could be used to set a pointer variable in the
> caller if test() were called in an appropriate way.

Well I changed the line with the first call to malloc to "*array =
malloc(10 * sizeof *array);".
It seems to work fine.
An other solution would be to let "test()" return "array", this also works
fine.


Sun, 25 Jul 2004 01:50:15 GMT  
 Pointer to pointer problem.


Quote:





>> >> int test(char **array)
>> >> {
>> >>         int i;

>> >>         array = malloc(10 * sizeof *array);

>> > 'array' is local to this function. It will go away when test() ends,
>> > leaving you with nothing to access the allocated storage.

>> Hmm... but char **result_array; defined in main() should still be valid.
>> What am I missing?

> You're missing that `*array' is never set.  `array' is a local
> variable, so modifying it doesn't affect anything in the caller,
> whereas `*array' could be used to set a pointer variable in the
> caller if test() were called in an appropriate way.

Thanks Ben. Sometimes I just can't see the automatics from the trees.

--
- Mark A. Odell
- Embedded Firmware Design, Inc.
- http://www.embeddedfw.com



Sun, 25 Jul 2004 01:52:17 GMT  
 Pointer to pointer problem.

Quote:


> > You're missing that `*array' is never set.??`array'?is?a?local
> > variable, so modifying it doesn't affect anything in the caller,
> > whereas `*array' could be used to set a pointer variable in the
> > caller if test() were called in an appropriate way.

> Well I changed the line with the first call to malloc to "*array =
> malloc(10 * sizeof *array);".

That is obviously wrong on the face of it.  `array' has type
`char **', so `*array' has type `char *', which means you are
assigning an array of `char *' sized elements to a `char *' when
you should be assigning an array of `char' sized elements.  Here
is the way you should write this statement:
        *array = malloc(10 * sizeof **array);
Rule of thumb: when using malloc(), the operand of `sizeof'
should always have one more level of dereferencing than the
object that receives malloc()'s return value.

But even then there is a problem: you are trying to receive a
`char **' in main() by passing in a `char **'.  That just can't
work.  You need to change the function to receive a `char ***'
and pass the address of the variable in main(), as `&array'.

Quote:
> It seems to work fine.

It will over-allocate memory and not do what you really want anyhow.

Quote:
> An other solution would be to let "test()" return "array", this
> also works fine.

That is probably simpler than using a triple pointer.
--
"When I have to rely on inadequacy, I prefer it to be my own."
--Richard Heathfield


Sun, 25 Jul 2004 02:16:49 GMT  
 Pointer to pointer problem.
On Tue, 05 Feb 2002 17:35:23 +0100, Usarin Heininga

Quote:

>Why doesn't this work.
>If I remove the first call to malloc "array = malloc(10 * sizeof *array);"
>, it works, but that would be incorrect code.
>If I move the first call to malloc to the main function, it also works, and
>this would be correct code, right ???
>But is it possible to keep the first call to malloc in the function test,
>and if yes, how should I do this ???

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

#include <string.h> /* for strcpy() */

Quote:

>int test(char **array);

>int test(char **array)

Nitpick: since the function always returns 0, it should return void.

Quote:
>{
>        int i;

>        array = malloc(10 * sizeof *array);

Since array is local to test(), the assignment only takes effect in
test(). array and result_array refer to *different* objects.  Just as
copy and original refer to different objects below.

void foo(int copy)
{
    copy=5;

Quote:
}

/* ... */

int original=0;
foo(original);
/* original still == 0 */

Quote:
>        if (array == NULL)
>        {
>                fprintf(stderr, "Memory allocation failed\n");
>                exit(EXIT_FAILURE);
>        }

>        for (i = 0; i < 10; ++i)
>        {      
>                array[i] = malloc(10 * sizeof **array);
>                if (array[i] == NULL)
>                {
>                        fprintf(stderr, "Memory allocation failed\n");
>                        exit(EXIT_FAILURE);
>                }      
>                strcpy(array[i], "usarin");
>        }      

>        printf("in the function 'test':\n");
>        for (i = 0; i < 10; ++i)
>                printf("array[%d] is: \t\t%s\n", i, array[i]);

>        return 0;
>}

The rest of this function is fine, though useless because of the local
assignment. This is why your program probably behaves until the end of
this function.

Quote:

>int main(void)
>{
>        char **result_array;
>        int i;

>        test(result_array);

Since memory was never allocated to result_array, it has an
indeterminate value at this point.

Quote:

>        printf("in the function 'main':\n");    
>        for (i = 0; i < 10; ++i)
>                printf("array[%d] is: \t\t%s\n", i, result_array[i]);

You probably crash in this loop.

Quote:

>        for (i = 0; i < 10; ++i)
>                free(result_array[i]);
>        free(result_array);

>        return 0;
>}

To have test() do what you want it to do, you can either have it
return a char ** (easier) or have it accept a char ***.

Here's the method returning a char **:

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

char **test(void)
{
        char **array;
        int i;

        array = malloc(10 * sizeof *array);
        if (array == NULL)
        {
                fprintf(stderr, "Memory allocation failed\n");
                exit(EXIT_FAILURE);
        }

        for (i = 0; i < 10; ++i)
        {      
                array[i] = malloc(10 * sizeof **array);
                if (array[i] == NULL)
                {
                        fprintf(stderr, "Memory allocation failed\n");
                        exit(EXIT_FAILURE);
                }      
                strcpy(array[i], "usarin");
        }      

        printf("in the function 'test':\n");
        for (i = 0; i < 10; ++i)
                printf("array[%d] is: \t\t%s\n", i, array[i]);

        return array;

Quote:
}

int main(void)
{
        char **result_array;
        int i;

        result_array=test();

        printf("in the function 'main':\n");    
        for (i = 0; i < 10; ++i)
                printf("array[%d] is: \t\t%s\n", i, result_array[i]);

        for (i = 0; i < 10; ++i)
                free(result_array[i]);
        free(result_array);

        return 0;

Quote:
}

Here's the 2nd method:

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

void test(char ***array)
{
        int i;

        *array = malloc(10 * sizeof **array);
        if (*array == NULL)
        {
                fprintf(stderr, "Memory allocation failed\n");
                exit(EXIT_FAILURE);
        }

        for (i = 0; i < 10; ++i)
        {      
                (*array)[i] = malloc(10 * sizeof ***array);
                if ((*array)[i] == NULL)
                {
                        fprintf(stderr, "Memory allocation failed\n");
                        exit(EXIT_FAILURE);
                }      
                strcpy((*array)[i], "usarin");
        }      

        printf("in the function 'test':\n");
        for (i = 0; i < 10; ++i)
                printf("array[%d] is: \t\t%s\n", i, (*array)[i]);

Quote:
}

int main(void)
{
        char **result_array;
        int i;

        test(&result_array);

        printf("in the function 'main':\n");    
        for (i = 0; i < 10; ++i)
                printf("array[%d] is: \t\t%s\n", i, result_array[i]);

        for (i = 0; i < 10; ++i)
                free(result_array[i]);
        free(result_array);

        return 0;

Quote:
}

Russ


Sun, 25 Jul 2004 03:30:23 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. pointer to pointer problem, please advice

2. Interesting Pointer-to-pointer problem

3. pointer->pointer problem

4. pointer to pointer problem

5. dyn mem alloc - pointer to pointer problem

6. pointer to pointer problem

7. Dereferencing f-pointers, arrays of f-pointers, pointers to f-pointers

8. memory leak: pointer->pointer->pointer->struct

9. Pointer of Pointers was Pointer of arrays...

10. memory block containing pointers, aka pointer to pointer i believe

11. pointers pointers pointers!!!

12. memory Leak: pointer->pointer->pointer->struct

 

 
Powered by phpBB® Forum Software