0
votes

I have such a function in C:

char **collect_character_distribution(char *buffer, long lSize)
{
    printf("Collecting character distribution...\n");
    long x;
    char distribution[256][2] = {0};

    for (x = 0; x < lSize; x++)
    {
            distribution[(int)buffer[x]][0] = (char) buffer[x];
            distribution[(int)buffer[x]][1]++;
    }
    return (char **) distribution;
}

I need to return two dimensional distribution array from the function above. And my main function is as the following:

int main()
{
    char *buffer;
    long lSize;
    struct Bar result = funct();
    char **distribution;
    buffer = result.x;
    lSize = result.y;
    distribution = collect_character_distribution(buffer, lSize);
    printf("%s\n", distribution);
    //struct Bar encoding_tree = generate_encoding_tree(distribution);
    return 0;
}

I get the following error:

warning: function returns address of local variable [-Wreturn-local-addr]

How can I fix this problem?

4
you have created a variable inside a loop and you are trying to pass its address outside, that makes no sense as the variable would be destroyed as soon as it loses scope - Swastik Padhi
@Arc676: interesting case - while that duplicate concerns exactly the same message (and the OP did not see it or did not look for it), I find myself questioning if the accepted answer is advisable in general. It does not even answer the question! - Jongware

4 Answers

2
votes

You are getting this error because that array is a local variable, and you are passing it outside its scope.

You need to use dynamic allocation for this

char **array = malloc(20 * sizeof(char *));
int i;
for(i=0; i != 20; ++i) {
    array[i] = malloc(20 * sizeof(char));
}

Now you can easily return array


EDIT 1

All you have to do is change

char distribution[256][2];

this to

char **array = malloc(20 * sizeof(char *));
int i;
for(i=0; i != 20; ++i) {
    array[i] = malloc(20 * sizeof(char));

}

EDIT 2

To print the strings, you should a loop

for(i=0; i<20; i++)
    printf("%s\n", distribution[i]);
1
votes

You're returning a pointer to a variable that is declared locally in the function. What you should do is declare the variable you want to store results in in the scope where you need these results. Then you pass a pointer to this variable into the function to write to. Something along these lines:

void collect_character_distribution(char *buffer, long lSize, char distribution[256][2])
{
        printf("Collecting character distribution...\n");
        long x;

        for (x = 0; x < 256; x++)
        {
            distribution[(int)x][0] = (char) x;
        }

        for (x = 0; x < lSize; x++)
        {

            distribution[(int)buffer[x]][1]++;
        }

}

int main()
{
        char *buffer;
        long lSize;
        struct Bar result = funct();
        char distribution[256][2] = {0};
        buffer = result.x;
        lSize = result.y;
        collect_character_distribution(buffer, lSize, distribution);
        int i;
        for ( i = 0; i < 256; i++ ) {
            printf("%c: %d\n", distribution[i][0], distribution[i][1]);
        }
        //struct Bar encoding_tree = generate_encoding_tree(distribution);
        return 0;
}
1
votes

You can pass char **distribution as a parameter and in your function use:

distribution = new char*[256];
distribution[0] = new char[2];
distribution[1] = new char[2];

Then you don't need to return distribution array from your function. The problem is local variables are destroyed after their scope ends and in your case distribution exists only in function collect_character_distribution.

1
votes

Its simple messages your funtion return's a local variable . Your array does not exist outside function block .

Inside your function you can do this -

char **distribution;
distribution=malloc(256*sizeof(char *));
for(int i=0;i<256;i++)
    distribution[i]=malloc(20*sizeof(distribution[0][0]));

Also in main , this -

printf("%s\n", distribution);

distribution is of type char ** , you can't pass it to %s specifier .

You can do it in loop -

for(int i=0;i<256;i++)
   printf("%s\n", distribution[i]);

Edit-

#include <stdio.h>
#include <stdlib.h>
char **collect_character_distribution(char *buffer, long lSize);
int main()
{
    char *buffer;
    long lSize;
    struct Bar result = funct();
    char **distribution;
    buffer = result.x;
    lSize = result.y;
    distribution = collect_character_distribution(buffer, lSize);      
    for(int i=0;i<256;i++)
        printf("%s\n", distribution[i]);
    //struct Bar encoding_tree = generate_encoding_tree(distribution);
    for(int i=0;i<256;i++)
          free(distribution[i]);
    free(distribution);
    return 0;
}

char **collect_character_distribution(char *buffer, long lSize)
{
        printf("Collecting character distribution...\n");
        long x;
        char **distribution;
        distribution=malloc(256*sizeof(char *));
        for(int i=0;i<256;i++)
            distribution[i]=malloc(20*sizeof(distribution[0][0]));
        for (x = 0; x < lSize; x++)
        {
                distribution[(int)buffer[x]][0] =  buffer[x];
                distribution[(int)buffer[x]][1]++;
        }
    return distribution;
 }