从方法返回后,本地结构变量不会被销毁

时间:2013-06-16 19:34:26

标签: c++

我有以下代码

#include <iostream>

struct mystruct
{
    float x;
};

void fun(mystruct* ptr)
{
    mystruct str = {10};
    ptr = &str;
    std::cout<<"bbq";
}

class cls
{
public:
   mystruct* ptr;
   void fun()
   {
        mystruct str = {10};
        ptr = &str;
        std::cout<<"bbq";
   }
};

int main()
{
    mystruct* ptr = new mystruct;
    fun(ptr);
    std::cout<<"bbq";

    cls obj;
    obj.fun();
    std::cout<<"bbq";

}

首先,指针ptr在函数中设置为本地结构的地址。当函数返回时,本地结构会按预期被破坏。

但是在类中有一个方法与成员指针相同,但是在方法重新运行后,我仍然设置了主成员指针。方法返回后,方法局部变量是否被销毁?

3 个答案:

答案 0 :(得分:4)

你的第一个例子是没有设置传递的指针,它正在设置指针的本地副本,因为它是按值传递的。您需要通过引用传递才能使用实际参数:

void fun(mystruct*& ptr);

函数返回后,本地变量 被销毁。但即使您在指针内部看到一个设置为局部变量的值,也不能假设局部变量被销毁。如果在将指针分配给过期对象后随时取消引用指针,则程序将具有未定义行为。

相关:Can a local variable's memory be accessed outside its scope?

答案 1 :(得分:1)

代码很奇怪。例如,在此功能中:

void fun(mystruct* ptr)
{
    mystruct str = {10}; // create a structure
    ptr = &str;  // make ptr point to it
    std::cout<<"bbq";
}

ptr被设置为某种东西,但它从未使用过。 ptr正在按值传递,因此无法在此函数之外产生效果。

在这里:

class cls
{
public:
   mystruct* ptr;
   void fun()
   {
        mystruct str = {10}; // create local variable
        ptr = &str;  // make ptr point to it
        std::cout<<"bbq";
   }
};

您正在将类成员ptr设置为指向局部变量,但是当函数返回时该变量将被销毁,因此ptr指向垃圾。 <{1}}在你的例子中没有被再次使用,所以没有伤害,但它仍然很奇怪。

在你的主要:

ptr

在这种情况下,不删除您分配的内容没有特别的害处,因为 这是程序的结束,但最好是动态删除 一般分配对象。

答案 2 :(得分:1)

我们可以通过这样做来导致失败:

struct mystruct
{
    float x;
    ~mystruct() { x = 99; }
};


class cls
{
public:
   mystruct* ptr;
   void fun()
   {
        mystruct str = {10};
        ptr = &str;
        std::cout<<"bbq";
   }
   void fun2()
   {
       std::cout << ptr->x << std::endl;
   }
};

... 
  obj.fun();
  obj.fun2();

现在,可能会发生obj.fun2();打印99,或者它可能会显示一些随机的其他数字,或者它可能会崩溃。这是因为“使用已被销毁的对象是未定义的行为” - 未定义的行为意味着C ++标准没有定义发生的事情,并且“任何事情都可能发生”,包括崩溃或挂起,或者它“按预期工作” ”。但是物体将被摧毁。由于原始代码在它指向的对象被销毁之后实际上没有使用ptr,所以没有任何不好的事情发生(实际上,它甚至不是示例代码中未定义的行为 - 它只是未定义为“使用指向对象”在对象被销毁之后“)。

编辑:

然而,

这段代码:

mystruct* ptr = new mystruct;
fun(ptr);
std::cout<<"bbq";

导致内存泄漏,因为永远不会删除ptr(如果fun在函数本身之外实际修改ptr,例如使用mystruct *&ptr作为参数,那么你将有一个不再被引用的mystruct的内存块,这是一个更糟糕的内存泄漏 - 当然是ptr中指向被破坏对象的值,所以你可以'无论如何都要使用ptr