【问题标题】:Returning an address of a local pointer variable to main() function将局部指针变量的地址返回给 main() 函数
【发布时间】:2018-01-01 16:23:05
【问题描述】:

在以下示例中,函数 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;
}

【问题讨论】:

  • 是的。是什么让你认为不是?它不返回“指针变量的地址”,而是“指针变量的”(当然,它是一个地址)。
  • @FelixPalmen 在 func() 和 main() 函数中打印相同的指针地址。见ide.geeksforgeeks.org/sULNzy
  • 你打印的不是指针的地址,而是指针的值指针的地址将是&amp;p in func resp。 &amp;ptrmain。当然,指针是一个地址(但是指针指向的对象的地址)。

标签: c function pointers malloc


【解决方案1】:

不,您确实返回指向局部变量(地址)的指针。那会做类似的事情

int i = 10;
return &i;

相反,您返回一个指向在堆上分配的对象的指针。

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

【讨论】:

  • 为了重新迭代,OP 返回的是一个指针的,而不是一个局部变量的地址
  • 为了完整起见,可能希望提及 - 在 OP 的示例中 - main()(或在 printf() 语句之后调用的其他函数)需要调用 free(ptr)。如果分配的内存在func() 内释放,则在main() 中访问*ptr 将有未定义的行为。
【解决方案2】:

func() 内部,p 是指向由malloc() 分配的内存的指针(或指向潜在分配的内存,因为malloc() 可能会失败,返回一个空指针;应该检查这一点)。如果成功,此内存分配将持续到显式为freed。

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

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

【讨论】:

    【解决方案3】:

    这是完全有效的。

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

    您返回的是某个malloced 内存的地址,不是局部变量的地址(分配在堆栈上)。这与strdup() 的工作方式非常相似。下面是 strdup() 的一个实现,取自 here

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

    这样做的一个明显缺点(正如“一些程序员老兄”所提到的)是freeing 的责任被传递给了调用者。

    【讨论】:

      【解决方案4】:

      这是一个有效且正确的代码,虽然有点混乱。

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

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

      之后函数返回指针值。

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

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

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

      这对孩子们来说是一项很好的学术锻炼。

      【讨论】:

      • "分配是通过取消引用 int 类型的指针变量来完成的。" 不,sizeof 只是对 type 的表达方式。这里没有取消引用。
      猜你喜欢
      • 1970-01-01
      • 2014-05-14
      • 2020-10-13
      • 1970-01-01
      • 2012-09-05
      • 2023-04-09
      • 1970-01-01
      相关资源
      最近更新 更多