0
votes

I get this error when compiling and have checked out other questions here with no further progress:

funciones.c: In function ‘Lyapunov’: ../funciones.c:55:2: warning: function returns address of local variable [-Wreturn-local-addr]
return rgb;

First of all, I call the 'Lyapunov' function here in another .c : *Please note that in this '.c' I have only posted the part of the code where Lyapunov is called and also the declaration of rgb.

unsigned char rgb[3];

while((int)linea>inicial){                  
        for(col=0;col<asize;col++){             
               rgb = Lyapunov(col,linea);

               fwrite(rgb, 3, image);
        }
        linea++;
}

and the Lyapunov function from where I get the warning is here:

#include "lyapunov.h"
#include <math.h>


#define CLAMP(x) (((x) > 255) ? 255 : ((x) < 0) ? 0 : (x))


unsigned char *Lyapunov(int ai, int bi){
    int n, m;
    double a, b, lambda, sum_log_deriv, prod_deriv, r, x, rgb_f[3];
    unsigned char rgb[3];   


    double lambda_min = -2.55;
    double lambda_max = 0.3959;

    a = amin + (amax-amin)/asize*(ai+0.5);
    b = bmin + (bmax-bmin)/bsize*(bi+0.5);
    x = 0.5;


        for (m = 0; m < seq_length; m++) {
            r = seq[m] ? b : a;
            x = r*x*(1-x);
        }

    sum_log_deriv = 0;
    for (n = 0; n < nmax; n++) {
        prod_deriv = 1;
        for (m = 0; m < seq_length; m++) {
                r = seq[m] ? b : a;

                prod_deriv *= r*(1-2*x); 
                x = r*x*(1-x);
        }
        sum_log_deriv += log(fabs(prod_deriv));
    }
    lambda = sum_log_deriv / (nmax*seq_length);

    if (lambda > 0) {
        rgb_f[2] = lambda/lambda_max;
        rgb_f[0] = rgb_f[1] = 0;
    } else {
        rgb_f[0] = 1 - pow(lambda/lambda_min, 2/3.0);
        rgb_f[1] = 1 - pow(lambda/lambda_min, 1/3.0);
        rgb_f[2] = 0;
    }


    rgb[0] = CLAMP(rgb_f[0]*255);
    rgb[1] = CLAMP(rgb_f[1]*255);
    rgb[2] = CLAMP(rgb_f[2]*255);

    return rgb;
}

I assume there must be some kind of 'malloc' but my attempts trying to fix it have been a disaster. Thank you in advance. Any help is appreciated.

4
Duplicate hundreds of times over. - Carl Norum
You're trying to return rgb, which is a local array, and which will therefore be out of scope when you return. - Paul R
Instead of returning an array pointer, I would pack 3 bytes of RGB into single int and return it, without messing with dynamic allocation. - Eugene Sh.

4 Answers

2
votes

You can use malloc as suggested, but looking at your code better idea would be to have a single static buffer passed to a function to have it's result (since you are using the buffer just once, and then discarding it's data), such that the function signature will be:

void Lyapunov(int ai, int bi, unsigned char rgb[]);

Then prior the use of the function you will need to define the buffer:

unsigned char rgb[3];

and then use it in your loop

Lyapunov(col,linea, rgb);

This way you will not need to worry about any memory leaks (resulting from the function).

1
votes
unsigned char rgb[3];

is local to function and the scope of this array is within the function Lyapunov so once you exit the function this memory is no more valid. So the warning you are getting is the right one which says never return the local variables address which will lead to undefined behavior when used outside its scope.

Have your memory allocated of heap and then return the pointer as shown below.

unsigned char *rgb = malloc(3);
1
votes

to avoid all the messy malloc/free calls, etc. define the rgb in the caller and pass the address to the function.

1
votes

You trying to return an array rgb which stops existing outside of its local scope ( also the scope of the function ), which stops existing when you return from the function. Arrays cannot be returned by value.

You can put the array in a struct:

struct rgb_hold
{
    char rgb[3] ;
} ;

and return the struct, which can be returned by value.