简体   繁体   English

将本地指针变量的地址返回给main()函数

[英]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. 在下面的示例中,函数func()本地指针变量地址返回给main()函数。 It's working fine in GCC. 它在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. 但是你确实有内存泄漏,因为你没有在任何地方free内存。 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). 应该通过调用函数的代码来执行free 调用 (除非它依次返回指针 ,其中责任继续在调用链上)。

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). func()内部, p是指向malloc()分配的malloc()的指针(或者可能分配的内存,因为malloc()可能会失败,返回一个空指针;应该检查这个)。 If successful, this memory allocation will persist until it is explicitly free d. 如果成功,则此内存分配将持续到明确free为止。

The value of p is returned to the calling function, main() in this case. 在这种情况下, p的值返回给调用函数main() 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 . p是指向成功分配的指针,或者是空指针,然后将返回的值(临时值,而不是左值)分配给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. 因此,分配的存储可以通过ptr访问, ptrfunc()返回之前p所持有的值的副本 ,尽管p本身的生命周期已经结束,因为func()已经返回。

Of course ptr should be free d when it is no longer needed to avoid memory leaks. 当然,当不再需要ptr来避免内存泄漏时,它应该是free And, there is potential undefined behavior here if malloc() fails, since then ptr is a null pointer. 并且,如果malloc()失败,则存在潜在的未定义行为,因为那时ptr是空指针。

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). 你要返回的是一些malloc ed内存的地址,而不是局部变量的地址(在堆栈上分配)。 This is very similar to how strdup() works. 这与strdup()工作方式非常相似。 Here's an implementation of strdup() taken from here . 这是strdup()的实现,取自此处

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. 其中一个明显的缺点(正如“一些程序员家伙”所提到的)是free转移的责任传递给调用者。

This is a valid and correct code, although bit confusing. 这是一个有效且正确的代码,虽然有点令人困惑。

The func is allocating memory of size int. func正在分配大小为int的内存。 The allocation is done via de-referencing a pointer variable of type int. 通过取消引用int类型的指针变量来完成分配。

Alter allocation the integer value of 10 is set in the memory. 更改分配整数值10在内存中设置。 10 should be set as integer (can be compiler dependent). 10应该设置为整数(可以依赖于编译器)。 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. 在main()中,返回的指针被设置为另一个整数指针。 This points to the original memory allocated by malloc(). 这指向malloc()分配的原始内存。

After that the de-referenced integer pointer is printed in the printf() statement. 之后,在printf()语句中打印取消引用的整数指针。 This will print the value of 10. 这将打印10的值。

What is missing is the free() call, which is not the good behaviour in here. 缺少的是free()调用,这不是这里的好行为。

This can be a good academic exercise for kids. 这对孩子们来说是一次很好的学术练习。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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