0

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?

3
  • 1
    Possible duplicate of stackoverflow.com/questions/6897914/… Commented Oct 31, 2015 at 13:31
  • 2
    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 Commented Oct 31, 2015 at 13:32
  • 1
    @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! Commented Oct 31, 2015 at 15:00

4 Answers 4

2

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]);
Sign up to request clarification or add additional context in comments.

5 Comments

Haris, could you present your answer fully?
@yusuf check if you can understand now
Haris, now I get this error on main function: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
@yusuf offcourse, you have a 2D array of char now. You need a loop to print all the strings in that.
@yusuf, try the changes i have made
1

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;
}

8 Comments

Hey yusuf, there are several other bugs in your code which will throw errors, which are separete from your original question. For example, you need to actually allocate distribution, and you can't print a two-dimensional char array with printf like that; you will need to loop through the strings in your array. I edited my code to reflect what I mean, but I didn't try compiling or debugging.
It's hard to say where that is coming from without seeing your full code and trying to narrow down where the segfault is being thrown. I would suggest accepting one of the answers here and opening a new question if you don't manage to debug it.
@MarcoTompitak @yusuf In main declare distribution as char ** distribution . In your code you access index out of bound thus UB.
Found one problem, I edited my code, like this it works for me.
What you're printing is probably not what you want. Guessing from your code, you probably want something like a: 1, b:4 etc.? I updated the code.
|
1

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 Comment

Ardavel, could you present your answer fully?
1

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;
 }

7 Comments

I don't understand the downvote . Please leave a comment .
I have upvoted you ameyCU :) Could you explain your answer briefly?
@Yusuf array you declare in function is a local variable , it cannot be accessed outside the function , when you do so , compiler issues a warning. For that ,we declare a char ** and allocate memory to it , so it retains it's values even after fucntions termination .
ameyCU, could you please present your answer fully?
@Yusuf ohh , yes , Either write *(distribution+i) there or distribution[i]. Sorry that went past , I made correction in code also .
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.