Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

warning: function returns address of local variable

Tags:

c

linux

gcc

I am writing a function in C to do some calculations. and I want to return that as an array value to another function this way.

455                         calculated_val = calculation(value_perf);


358 int calculation(double* dataset){
359
360         double calculated[8] = {};
361         calculated[0] = dataset[7]/dataset[5];
362         calculated[1] = (dataset[0] + dataset[1] + dataset[2] - dataset[3] - dataset[4])/(dataset[5]);
363         calculated[2] = dataset[3]/dataset[5];
364         calculated[3] = dataset[6]/dataset[5];
365         calculated[4] = dataset[8]/dataset[5];
366         calculated[5] = dataset[9]/dataset[10];
367         calculated[6] = dataset[11]/dataset[5];
368         calculated[7] = dataset[12]/dataset[5];
369         return calculated;
370 }

While, I am doing so..I get the following warnings and I don't understand them.

369:2: warning: return makes integer from pointer without a cast [enabled by default]
369:2: warning: function returns address of local variable [enabled by default]

Is there something I missed out fundamentally? Please give me some hints/solutions.

like image 953
pistal Avatar asked Sep 18 '13 07:09

pistal


3 Answers

double calculated[8]

Allocates memory on the stack, which will be unwound when the function returns and thus not safe for the calling function to access.

Instead, use

double* calculated = malloc(8 * sizeof(double));

to allocate it on the heap, which can then shared across your program.

Edit

I'm not sure what was intended by return an int. To return your heap allocated calculation of 8 doubles:

#include "stdlib.h"
// ...
double* calculation(double* dataset){
    double* calculated = (double*)malloc(8 * sizeof(double));
    calculated[0] = dataset[7]/dataset[5];
    // Other assignments ... 
    return calculated;
}

Note that your calling code needs to be adjusted to accomodate the double* return as well.

As per Gauthier's comment, ownership of the allocated array transfers from 'calculation' to the calling function, which must release it once it is no longer needed.

like image 104
StuartLC Avatar answered Nov 17 '22 07:11

StuartLC


You can take an additional parameter where the result is returned.

void calculation(double* dataset, double * result)

And call the function as below

calculation(value_perf, calculated_val);

where calculated_val is assumed to be declared as double array.

For convenience of using the returned value in another function in the same expression, you can return the same parameter.

double * calculation(double* dataset, double * result)
{
    ...
    return result;
}
like image 36
user1969104 Avatar answered Nov 17 '22 07:11

user1969104


Firstly, your function's return type is incorrect. It should probably be a pointer to a double.

Secondly, you are returning the address of a local variable which is allocated on the stack and as soon as you return from the function, that variable goes out of the picture and similarly it's address.

So, if you really want to return the address, then you should use:

double* calculated = malloc(sizeof(double)*8);
like image 1
Sankalp Avatar answered Nov 17 '22 08:11

Sankalp