1

我有以下代码

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

}

首先在函数 fun 中将指针 ptr 设置为局部结构的地址。当函数返回时,本地结构会按预期销毁。

但是在类中有一个方法对成员指针做同样的事情,但是在方法返回并且我回到主成员指针之后仍然设置。方法返回后方法局部变量不会被销毁吗?

4

3 回答 3

4

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

void fun(mystruct*& ptr);

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

相关:可以在其范围之外访问局部变量的内存吗?

于 2013-06-16T19:40:47.637 回答
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指向垃圾。 ptr在您的示例中没有再次使用,所以没有造成伤害,但它仍然很奇怪。

在你的主要:

int main()
{
    mystruct* ptr = new mystruct; // make ptr point do a dynamically allocated object.
    fun(ptr); // call fun with a copy of the pointer
    std::cout<<"bbq";

    cls obj;
    obj.fun();
    std::cout<<"bbq";
    // That object that ptr is pointing to is never deleted.

}

在这种情况下不删除您分配的内容并没有什么特别的危害,因为这是您的程序的结尾,但一般来说删除动态分配的对象是一个好习惯。

于 2013-06-16T19:42:19.773 回答
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();

Now, it may happen that obj.fun2(); prints 99, or it may show some random other number, or it may crash. This is because the "use of an object that has been destroyed is undefined behaviour" - undefined behaviour means that the C++ standard does not define what happens, and "anything could happen", including crashing or hanging, or it works "as you expect". But the object will be destroyed. Since the original code doesn't actually USE ptr after the object it points to was destroyed, nothing bad happens (in fact, it's not even undefined behaviour in the example code - it is only undefined to "use pointed at object after the object has been destroyed").

Edit:

this code, however:

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

causes a memory leak, since ptr is never deleted (and if fun where to actually modify ptr outside of the function itself, e.g by using mystruct *&ptr as the argument, then you would have a memory block for mystruct that is no longer referenced, which is an even worse memory leak - and of course a value in ptr that points to destroyed object, so you can't use ptr anyway)

于 2013-06-16T19:44:51.360 回答