简体   繁体   中英

Returning an address of a local pointer variable to main() function

In the following example, function func() returning an address of a local pointer variable to main() function. It's working fine in GCC.

So, Is it well-defined behaviour?

#include <stdio.h>
#include <stdlib.h>

int *func(void);

int *func(void)
{
   int *p;
   p = malloc(sizeof *p);
   *p = 10;
   return p;
}

int main() 
{
    int *ptr = func();
    printf("%d\n",*ptr);
    return 0;
}

No, you do not return a pointer to (address of) a local variable. That would be doing something like

int i = 10;
return &i;

Instead you return a pointer to an object allocated on the heap.

You do have a memory leak though, since you don't free the memory anywhere. Calling free should be done by the code calling your function (unless it in turn return the pointer value , where the responsibility continues upt he call-chain).

Inside func() , p is a pointer to memory allocated by malloc() (or to potentially allocated memory, since malloc() can fail, returning a null pointer; this should be checked for). If successful, this memory allocation will persist until it is explicitly free d.

The value of p is returned to the calling function, main() in this case. p is either a pointer to a successful allocation, or is a null pointer, and the returned value (which is temporary, and not an lvalue) is then assigned to ptr . So, the allocated storage can be accessed through ptr , which is a copy of the value held by p before func() returned, though the lifetime of p itself has ended now that func() has returned.

Of course ptr should be free d when it is no longer needed to avoid memory leaks. And, there is potential undefined behavior here if malloc() fails, since then ptr is a null pointer.

This is perfectly valid.

What is not guaranteed is what will happen to the variables on the stack frame once a function returns and the stack frame shrinks.

What you are returning is an address to some malloc ed memory and not the address of a local variable (allocated on the stack). This is very similar to how strdup() works. Here's an implementation of strdup() taken from here .

char *
strdup(str)
    const char *str;
{
    size_t len;
    char *copy;

    len = strlen(str) + 1;
    if (!(copy = malloc((u_int)len)))
        return (NULL);
    bcopy(str, copy, len);
    return (copy);
}

One obvious downside of this (as mentioned by "Some programmer dude") is that the responsibility of free ing is passed on to the caller.

This is a valid and correct code, although bit confusing.

The func is allocating memory of size int. The allocation is done via de-referencing a pointer variable of type int.

Alter allocation the integer value of 10 is set in the memory. 10 should be set as integer (can be compiler dependent). But definitely will not be of greater than the size of integer so should be safe operation.

After that the pointer value is returned by the function.

In main() the returned pointer is set to another integer pointer. This points to the original memory allocated by malloc().

After that the de-referenced integer pointer is printed in the printf() statement. This will print the value of 10.

What is missing is the free() call, which is not the good behaviour in here.

This can be a good academic exercise for kids.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM