views:

845

answers:

8

Say you have the following function:

char *getp()
{
    char s[] = "hello";
    return s;
}

Since the function is returning a pointer to a local variable in the function to be used outside, will it cause a memory leak?

P.S. I am still learning C so my question may be a bit naive...

[Update]
So, if say you want to return a new char[] array (ie maybe for a substring function), what do you return exactly? Should it be pointer to an external variable ? ie a char[] that is not local to the function?

+16  A: 

It won't cause a memory leak. It'll cause a dangling reference. The local variable is allocated on the stack and will be freed as soon as it goes out of scope. As a result, when the function ends, the pointer you are returning no longer points to a memory you own. This is not a memory leak (memory leak is when you allocate some memory and don't free it).

[Update]: To be able to return an array allocated in a function, you should allocate it outside stack (e.g. in the heap) like:

char *test() {
    char* arr = malloc(100);
    arr[0] = 'M';
    return arr;
}

Now, if you don't free the memory in the calling function after you finished using it, you'll have a memory leak.

Mehrdad Afshari
+10  A: 

No, it wont leak, since its destroyed after getp() ends;

It will result in undefined behaviour, because now you have a pointer to a memory area that no longer holds what you think it does, and that can be reused by anyone.

A memory leak would happen if you stored that array on the heap, without executing a call to free().

char* getp(){

   char* p = malloc(N);
   //do stuff to p
   return p;
}

int main(){
    char* p = getp();
    //free(p) No leak if this line is uncommented
    return 0;
}

Here, p is not destroyed because its not in the stack, but in the heap. However, once the program ends, allocated memory has not been released, causing a memory leak ( even though its done once the process dies).

[UPDATE]

If you want to return a new c-string from a function, you have two options.

  • Store it in the heap (as the example above or like this real example that returns a duplicated string);
  • Pass a buffer parameter

for example:

    //doesnt exactly answer your update question, but probably a better idea.
    size_t foo (const char* str, size_t strleng, char* newstr);

Here, you'd have to allocate memory somewhere for newstr (could be stack OR heap) before calling foo function. In this particular case, it would return the amount of characters in newstr.

Tom
+7  A: 

It's not a memory leak because the memory is being release properly.

But it is a bug. You have a pointer to unallocated memory. It is called a dangling reference and is a common source of errors in C. The results are undefined. You wont see any problems until run-time when you try to use that pointer.

Robert Cartaino
A: 

s is a stack variable - it's automatically de-referenced at the end of the function. However, your pointer won't be valid and will refer to an area of memory that could be overwritten at any point.

Rob Knight
It's not de-referenced, but no longer allocated on the stack.
Corey Ross
+2  A: 

It will not cause memory leak, but it will cause undefined behavior. This case is particularly dangerous because the pointer will point somewhere in the program's stack, and if you use it, you will be accessing random data. Such pointer, when written through, can also be used to compromise program security and make it execute arbitrary code.

zvrba
+3  A: 

Auto variables are destroyed at the end of the function call; you can't return a pointer to them. What you're doing could be described as "returning a pointer to the block of memory that used to hold s, but now is unused (but might still have something in it, at least for now) and that will rapidly be filled with something else entirely."

Aric TenEyck
+1 for not using the word "stack".
sigjuice
+1  A: 

I've deleted my earlier answer after putting the code in a debugger and watching the disassembly and the memory window.

The code in the question is invalid and returns a reference to stack memory, which will be overwritten.

This slightly different version, however, returns a reference to fixed memory, and works fine:

char *getp()
{
    char* s = "hello";
    return s;
}
abelenky
char s* ??? Is this allowed in C???
Alphaneo
typo.... you know I meant char* s
abelenky
+2  A: 

No-one else has yet mentioned another way that you can make this construct valid: tell the compiler that you want the array "s" to have "static storage duration" (this means it lives for the life of the program, like a global variable). You do this with the keyword "static":

char *getp()
{
    static char s[] = "hello";
    return s;
}

Now, the downside of this is that there is now only one instance of s, shared between every invocation of the getp() function. With the function as you've written it, that won't matter. In more complicated cases, it might not do what you want.

PS: The usual kind of local variables have what's called "automatic storage duration", which means that a new instance of the variable is brought into existence when the function is called, and disappears when the function returns. There's a corresponding keyword "auto", but it's implied anyway if you don't use "static", so you almost never see it in real world code.

caf
Are the `static` references stored on the Heap?
Andreas Grech
No, they're loaded/created at program startup, so memory for them is usually allocated in a similar way to the memory that holds the program text itself.
caf