繁体   English   中英

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

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

在下面的示例中,函数func()本地指针变量地址返回给main()函数。 它在GCC中运行良好。

那么, 它是明确定义的行为吗?

#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;
}

不,您返回指向本地变量(的地址)的指针。 那会是这样的

int i = 10;
return &i;

而是返回指向堆上分配的对象的指针。

但是你确实有内存泄漏,因为你没有在任何地方free内存。 应该通过调用函数的代码来执行free 调用 (除非它依次返回指针 ,其中责任继续在调用链上)。

func()内部, p是指向malloc()分配的malloc()的指针(或者可能分配的内存,因为malloc()可能会失败,返回一个空指针;应该检查这个)。 如果成功,则此内存分配将持续到明确free为止。

在这种情况下, p的值返回给调用函数main() p是指向成功分配的指针,或者是空指针,然后将返回的值(临时值,而不是左值)分配给ptr 因此,分配的存储可以通过ptr访问, ptrfunc()返回之前p所持有的值的副本 ,尽管p本身的生命周期已经结束,因为func()已经返回。

当然,当不再需要ptr来避免内存泄漏时,它应该是free 并且,如果malloc()失败,则存在潜在的未定义行为,因为那时ptr是空指针。

这完全有效。

不能保证的是,一旦函数返回并且堆栈帧收缩,堆栈帧上的变量会发生什么。

你要返回的是一些malloc ed内存的地址,而不是局部变量的地址(在堆栈上分配)。 这与strdup()工作方式非常相似。 这是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);
}

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

这是一个有效且正确的代码,虽然有点令人困惑。

func正在分配大小为int的内存。 通过取消引用int类型的指针变量来完成分配。

更改分配整数值10在内存中设置。 10应该设置为整数(可以依赖于编译器)。 但绝对不会大于整数的大小所以应该安全操作。

之后,函数返回指针值。

在main()中,返回的指针被设置为另一个整数指针。 这指向malloc()分配的原始内存。

之后,在printf()语句中打印取消引用的整数指针。 这将打印10的值。

缺少的是free()调用,这不是这里的好行为。

这对孩子们来说是一次很好的学术练习。

暂无
暂无

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

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