C 将局部指针变量的地址返回到main()函数

C 将局部指针变量的地址返回到main()函数,c,function,pointers,malloc,C,Function,Pointers,Malloc,在下面的示例中,函数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(

在下面的示例中,函数
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*func(无效);
int*func(无效)
{
int*p;
p=malloc(sizeof*p);
*p=10;
返回p;
}
int main()
{
int*ptr=func();
printf(“%d\n”,*ptr);
返回0;
}
否,您不会返回指向局部变量(地址)的指针。那就是做类似的事情

int i = 10;
return &i;
而是返回一个指向堆上分配的对象的指针


不过,您确实存在内存泄漏,因为您没有
在任何地方释放内存。调用
free
应该由调用函数的代码来完成(除非它反过来返回指针值,在指针值中,调用链的责任继续向上)。

这是完全有效的

无法保证的是,一旦函数返回且堆栈帧收缩,堆栈帧上的变量将发生什么情况

返回的是某个
malloc
ed内存的地址,而不是本地变量(在堆栈上分配)的地址。这与
strdup()
的工作原理非常相似。下面是取自的
strdup()
的一个实现


这样做的一个明显的缺点(正如“一些程序员杜德”所提到的)是
免费
的责任转移到了调用者身上。

这是一个有效且正确的代码,尽管有点混乱

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

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

之后,函数返回指针值

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

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

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

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

func()
中,
p
是一个指向
malloc()
分配的内存的指针(或者指向潜在分配的内存,因为
malloc()
可能会失败,返回空指针;应该检查是否存在此问题)。如果成功,此内存分配将一直持续,直到显式地
free
d

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


当然,
ptr
在不再需要时应该是免费的,以避免内存泄漏。而且,如果
malloc()
失败,这里可能存在未定义的行为,因为
ptr
是一个空指针。

是的。你凭什么认为不是?它不返回“指针变量的地址”,而是返回“指针变量的值”(当然,这是一个地址)。@FelixPalmen在func()和main()函数中打印相同的指针地址。查看打印内容,不是指针的地址,而是指针的值。指针的地址将是
func
resp中的
&p
<代码>&ptr
main
中。当然,指针的值是一个地址(但指针指向的对象的地址)。要重新迭代,OP返回的是指针的值,而不是局部变量的地址。为了完整性起见,可能希望在OP的示例中提到-
main()
(或在
printf之后调用的其他函数()
语句)将需要调用
free(ptr)
。如果在
func()
中释放malloced内存,则在
main()
中访问
*ptr
将具有未定义的行为。“分配是通过取消引用int类型的指针变量完成的。”不,
sizeof
只对表达式的类型进行操作。此处不进行解引用。
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);
}