Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Work around error 'Address of stack memory associated with local variable returned'

I am trying to call a method that will generate a 2D char array (array of strings) and return it to be used in another function.

My example:

char ** example(void)
{
    char *test[3];

    int i;
    for (i = 0; i < 3; i++) {
        test[i] = malloc(3 * sizeof(char));
    }

    test[foo][bar] = 'baz'; // of course I would declare 'foo' and 'bar'
    // ...
    // ...

    return test;
}

And then I would like to be able to use the array as follows:

void otherMethod(void)
{
    char ** args = example();
    // do stuff with args
}

The problem is that this produces the error:

warning: address of stack memory associated with local variable 'test' returned [-Wreturn-stack-address]

I could solve this problem by defining test in the global scope as opposed to locally, but I would very much rather not do this as it seems messy, especially if I am to have several of these.

Is there a way to create and return an array of strings in C without defining it globally?

like image 232
tam5 Avatar asked Dec 11 '15 15:12

tam5


3 Answers

You are on the right track. All you need to do is to change the allocation of the test[3]; itself from automatic (aka "stack") to dynamic (aka "heap"):

char **test = malloc(3 * sizeof(char*));

This makes it legal to return test from your function, because it would no longer be returning an address associated with stack allocation.

Of course the caller would be required to free both the pointers inside the return, and the return itself. You may want to consider supplying a helper function for that.

Another approach would be to take char test[] as a function parameter:

void example(char *test[], size_t count) {
    for (size_t i = 0 ; i < count ; i++) {
        test[i] = malloc(3 * sizeof(char));
    }
    ...
    // return is not required
}

Now the caller would have to pass an array of suitable size into your function, so that you could avoid allocating it.

like image 110
Sergey Kalinichenko Avatar answered Nov 10 '22 06:11

Sergey Kalinichenko


Using malloc:

char ** example(void)
{
    char** test = malloc(sizeof(char*) * 3);

    int i;
    for (i = 0; i < 3; i++) {
        test[i] = malloc(3 * sizeof(char));
    }

    test[foo][bar] = 'baz'; // of course I would declare 'foo' and 'bar'
    // ...
    // ...

    return test;
}
like image 22
cadaniluk Avatar answered Nov 10 '22 08:11

cadaniluk


Use static:

static char *test[3];
like image 1
Sapphire_Brick Avatar answered Nov 10 '22 07:11

Sapphire_Brick