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

时间:2017-07-26 11:16:35

标签: c function pointers malloc

在以下示例中,函数func()本地指针变量的地址返回到main()函数。它在海湾合作委员会中运作良好。

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

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

4 个答案:

答案 0 :(得分:9)

不,你做返回一个指向本地变量(的地址)的指针。这将是类似

的事情
int i = 10;
return &i;

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

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

答案 1 :(得分:3)

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

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

当不再需要时,free应该malloc()以避免内存泄漏。并且,如果ptr失败,则此处存在潜在的未定义行为,因为>>> job = group([ ... add.subtask((2, 2)), ... add.subtask((4, 4)), ... add.subtask((8, 8)), ... add.subtask((16, 16)), ... add.subtask((32, 32)), ... ]) >>> result = job.apply_async() >>> result.join() [4, 8, 16, 32, 64] 是空指针。

答案 2 :(得分:1)

这完全有效。

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

您要返回的是某个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); } 的{​​{1}}实现。

free

一个明显的缺点(正如“一些程序员家伙”所提到的)是<?php $test = array(); $test2[] = array( 'key1' => '111', 'key2' => '111', 'key3' => '111', ); $test2[] = array( 'key1' => '222', 'key2' => '222', 'key3' => '222', ); $test['tax_query'] = array( 'relation' => 'AND', $test2, ); print_r($test); ?> 的责任传递给调用者。

答案 3 :(得分:1)

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

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

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

之后,函数返回指针值。

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

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

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

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