如果我们直接返回类实例的内存位置会发生什么?

时间:2015-01-22 23:02:32

标签: c++ class object-lifetime

主要功能代码:

PNG* allocate(size_t w, size_t h) {
    PNG ret(w, h);
    return &ret;
}

int main() {
    PNG * image = allocate(256, 512);
    delete image;
    return 0;
}

假设定义了适当的PNG类。我的问题是关于allocate();和& ret。通常在调用函数之后,清除每个创建的实例(仅新复制数据)。在这种情况下,& ret指向新创建的ret的位置。但似乎在运行函数后,ret将被删除,因此,PNG *图像会表现得很疯狂。

这是真的吗?如果是这样,修复代码的方法是什么?

此外,图片不是由创建的,因此使用删除是明智的吗?

2 个答案:

答案 0 :(得分:2)

要按字面意思回答您的问题,修复此代码的方法是不要在调用delete时未给您的任何指针上调用new

delete做了两件事:

  1. 它调用对象的析构函数
  2. 它将对象的内存释放回运行时的分配器
  3. 在这种情况下,ret中创建的allocate对象将在函数退出时自动销毁,因此尝试调用其析构函数没有意义。该对象也没有分配给运行时提供的内存,所以谈论释放内存也没有意义。

答案 1 :(得分:0)

您返回函数本地对象的内存地址(临时),这意味着它已在堆栈上创建。

当函数返回时,对象将被自动删除(当它从堆栈中弹出时)

在函数返回后访问此对象是未定义的行为,因为您现在正在读取不再分配给对象的内存。

您应该使用delete的唯一时间是您在堆上分配内存(使用new