[英]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
访问, ptr
是func()
返回之前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.