C++ Warning: Address of Local Variable

warning: function returns address of local variable [enabled by default]

The chktype function allocates memory for an automatic variable on the stack, and then returns the address of this variable (i.e., a pointer to this variable).

The problem is that variables allocated on the stack are automatically destroyed whenever they go out of scope (i.e., control passes outside of the curly braces that define the function).

This means that you're essentially returning a pointer to an invalid memory location, which is bad news. In C-speak, it's undefined behavior. In practical speak, it results in bad output or perhaps even a crash.

char *chktype(char *Buffer, int Size)
{
// This pointer variable is allocated on the stack, but that's okay because
// it's a pointer to a string literal, which are always constant.
// (Technically, you should add the "const" qualifier to the declaration.)
const char *strng = "Content-Type: ";

int sz;
char *found = strstr (Buffer, strng);
char *found1 = strstr(found, "\r\n");
sz=strlen(found)-strlen(found1);

// Like all the above variables, the one is also allocated on the stack.
// But it's the source of your problem here, because it's the one that
// you are returning at the end of the function.
// Problem is, it goes away at the end of the function!
char type[sz];
strncpy(type, found1, sz-1);
return(type);
}

The correct way to return a char* from a function is to allocate new memory from the heap using the malloc (or calloc) function. That means that the caller of the function is going to be responsible for freeing the memory used by the returned value, otherwise your program will leak memory.

(Always put this requirement into the documentation for your function! Even if "documentation" means a comment above the declaration.)

For example, change your code to look like this:

char *chktype(char *Buffer, int Size)
{
// This pointer variable is allocated on the stack, but that's okay because
// it's a pointer to a string literal, which are always constant.
// (Technically, you should add the "const" qualifier to the declaration.)
const char *strng = "Content-Type: ";

int sz;
char *found = strstr (Buffer, strng);
char *found1 = strstr(found, "\r\n");
sz=strlen(found)-strlen(found1);

char *type = malloc(sz); // allocate memory from the heap
strncpy(type, found1, sz-1);
return(type);
}

Now, in the caller of the chktype function, you must make sure that you call free whenever you are finished with its return value:

char *type = chktype(...);
// do something
free(type);

Note that robust code should test the result of malloc for a null pointer to make sure that it did not fail to allocate the requested memory. If so, you need to handle the error somehow. For clarity, that isn't shown above.

C Warning: Function returns address of local variable

Some other answers suggest that you malloc something and return it. This is bad practice in the same sense as in C++, when you new something in a function and the caller is supposed to delete it (who has ownership?)

There is a reason that many C APIs have the format of:

function(buf, length);

Meaning that the CALLER supplies the buffer and how long it is. IT is the caller's responsibility to allocate and de-allocate this buffer and your function should use it, and check that you're not going to overflow the length.

Do not malloc and return. It's just asking for trouble.

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

You can imagine the function definition and its call

long address = address(one);
//...
uint64_t address( char * strin)
{
return (uint64_t) &strin;
}

the following way

long address = address(one);
//...
uint64_t address( void )
{
char * strin = one;
return (uint64_t) &strin;
}

As you see variable strin is a local variable of the function. It will be destroyed after exiting the function. Thus its address after exiting the function will be invalid. And the compiler warns you about this.

To avoid the warning you could write the function at least the following way

uint64_t address( char ** strin)
{
return (uint64_t) &*strin;
}

and call it like

long address = address(&one);

warning: address of local variable 'angles' returned [-Wreturn-local-addr]

float angles[3] = { ... };

defines a local array.

The statement

return angles;

returns a pointer to the first element of the array.

However, the array is destructed as soon as the function returns. Hence, the returned pointer is a dangling pointer.

That's what the compiler is warning you about. If you dereference the returned pointer in the calling function, you invoke undefined behavior.

In order to return a pointer to an array that will remain valid after the function returns, you need to allocate dynamic memory and return the dynamic memory.

float* Creature::eulerAngles(const float &q0, const float &q1,
const float &q2, const float &q3)
{
float* angles = new float[3];
angles[0] = atan2(2 * (q0*q1 + q2*q3), 1 - 2 * (q1*q1 + q2*q2));
angles[1] = asin( 2 * (q0*q2 - q3*q1));
angles[2] = atan2(2 * (q0*q3 + q1*q2), 1 - 2 * (q2*q2 + q3*q3));

return angles;
}

Keep in mind that if you do the above, you'll have to make sure to call delete [] on the returned pointer in the calling function.

To avoid the hassles of manually allocating and deallocating memory, you can use std::vector<float> as your return type.

std::vector<float> Creature::eulerAngles(const float &q0, const float &q1,
const float &q2, const float &q3)
{
std::vector<float> angles(3);
angles[0] = atan2(2 * (q0*q1 + q2*q3), 1 - 2 * (q1*q1 + q2*q2));
angles[1] = asin( 2 * (q0*q2 - q3*q1));
angles[2] = atan2(2 * (q0*q3 + q1*q2), 1 - 2 * (q2*q2 + q3*q3));

return angles;
}

With this, memory management is done automatically for you.

Since the size of the array is fixed at 3, using std::array<float, 3> is better than using std::vector<float>:

std::array<float, 3> Creature::eulerAngles(const float &q0, const float &q1, const float &q2, const float &q3)
{
std::array<float, 3> angles;
angles[0] = atan2(2 * (q0*q1 + q2*q3), 1 - 2 * (q1*q1 + q2*q2));
angles[1] = asin( 2 * (q0*q2 - q3*q1));
angles[2] = atan2(2 * (q0*q3 + q1*q2), 1 - 2 * (q2*q2 + q3*q3));

return angles;
}

C Returning char[] Warning returns address of local variable

char line[30]; is an array with automatic storage duration. Memory where it resides is deallocated once the execution goes out of the scope of your function, thus pointer to this memory that you return becomes invalid (dangling pointer).

Trying to access memory, that has already been deallocated, results in undefined behaviour.

You can allocate your array dynamically and let the caller explicitly deallocate it:

char *getLine() {
char* line = malloc(30);
...
return line;
}

// somewhere:
char* line = getLine();
...
free(line);

How to fix function returns address of local variable error in C?

To begin with, judging from return "error", you want buffer to be an array of characters, not an array of pointers to characters. Fix this first.

As for the local variable issue, simply modify the function into this:

void readFile (const char* filename, size_t chunk, char buffer[chunk])

This forces the caller to deal with the allocation and your function only needs to focus on its designated task.



Related Topics



Leave a reply



Submit