首页 文章

为什么返回指向局部变量或参数的指针是不好的做法? [重复]

提问于
浏览
2

这个问题在这里已有答案:

我在学习指南中发现了这个问题,我不确定为什么返回指向局部变量/参数的指针会很糟糕 . 有任何想法吗?

6 回答

  • 5

    它不是一个"bad practice"(意味着它可能会导致问题),而是一种将是 absolutely cause undefined behavior 的实践 . 它's like dereferencing a null pointer: don' t并且期望您的程序在逻辑限制内运行 .

    说明:

    当声明局部变量(包括参数)时,它被赋予自动存储,这意味着编译器负责为变量分配内存,然后在程序员的帮助下解除分配该内存 .

    void foo(int bar)
    {
        int baz;
    } //baz and bar dissappear here
    

    当变量'lifetime终止时(例如函数返回时),编译器将履行其承诺,并且销毁函数本地的所有自动变量 . 这意味着任何指向这些变量的指针现在指向程序认为“免费”执行任何操作的垃圾内存 .

    返回值时,这不是问题:程序找到一个新位置来放置值 .

    int foo(int bar)
    {
        int baz = 6;
        return baz + bar; //baz + bar copied to new memory location outside of foo
    } //baz and bar disapear
    

    返回指针时,指针的值将照常复制 . 但是,指针仍指向同一位置,现在是垃圾:

    int* foo(int bar)
    {
        int baz = 6;
        baz += bar;
        return &baz; //(&baz) copied to new memory location outside of foo
    } //baz and bar disapear! &baz is now garbage memory!
    

    访问此内存是不明确的行为,因此您的程序几乎肯定会以某种方式行为不端 . 例如,我曾经fell victim to this exact problem,虽然我的程序没有崩溃或终止,但我的变量开始降级为垃圾值,因为编译器覆盖了"free"内存 .

  • 2

    因为该变量的地址属于创建它的堆栈帧 . 没有其他的 . 一旦你 return ,该激活记录被清理干净,之前的任何内容现在都是未定义的 .

  • 2

    局部变量存储在堆栈中 . 存储在堆栈中的值会在函数/代码块退出时被销毁(即,您到达函数的末尾 - 从技术上讲,它们可以持续更长时间,但这是另一个讨论) . 因此,指针(指向存储器中特定位置的地址)指向可能不再存在的值 .

  • 0

    函数返回后,堆栈中的局部变量和参数已被解除分配 . 它们可能仍然存在,但是没有任何保证,当某些东西决定使用堆栈时,它们肯定会受到打击 .

    使用WP中的图表:

    Stack diagram

    顶部的堆栈指针是可以安全地分配和放置新变量的位置(例如调用函数时) . 当函数(例如DrawLine)返回时,它们被从堆栈中取出(堆栈指针只是递增,因此它不再指向超出范围的绿色变量) . 稍后出现并分配和使用堆栈空间的任何内容都将破坏旧值 .

  • 1

    如果在函数返回后返回指向局部变量的指针,则它超出范围 . 从那时起,如果您访问返回的指针,则它是未定义的行为 .

  • 2

    因为 will 会导致程序中出现未定义的行为 .

相关问题