【问题标题】:Copy semantic, Deep copy (C++)复制语义,深拷贝 (C++)
【发布时间】:2020-02-24 11:15:00
【问题描述】:

我有 c++ 中复制语义的问题

这是我的代码

#include <iostream>

class DeepCopy
{
private:
    int *_myInt;

public:
    DeepCopy(int val)
    {
        _myInt = (int *)malloc(sizeof(int));
        *_myInt = val;
        std::cout << "resource allocated at address " << _myInt << std::endl;
    }
    ~DeepCopy()
    {
        free(_myInt);
        std::cout << "resource freed at address " << _myInt << std::endl;
    }
    DeepCopy(DeepCopy &source)
    {
        _myInt = (int *)malloc(sizeof(int)); // line 1 
        *_myInt = *source._myInt;  // line 2
        std::cout << "resource allocated at address " << _myInt << " with _myInt = " << *_myInt << std::endl;
    }
    DeepCopy &operator=(DeepCopy &source)
    {
        _myInt = (int *)malloc(sizeof(int));
        std::cout << "resource allocated at address " << _myInt << " with _myInt=" << *_myInt << std::endl;
        *_myInt = *source._myInt;
        return *this;
    }
    void printOwnAddress() { std::cout << "Own address on the stack is " << this << std::endl; }
    void printMemberAddress() { std::cout << "Managing memory block on the heap at " << _myInt << std::endl << std::endl; }

};

int main()
{
    DeepCopy source(42);
    source.printOwnAddress();
    source.printMemberAddress();
    DeepCopy dest1(source);
    dest1.printOwnAddress();
    dest1.printMemberAddress();

    source.printOwnAddress();
    source.printMemberAddress();
    return 0;
}

真正的结果是在终端:

resource allocated at address 0x2511c20
Own address on the stack is 0x7ffdf539da00
Managing memory block on the heap at 0x2511c20

resource allocated at address 0x2512050 with _myInt = 42
Own address on the stack is 0x7ffdf539da10
Managing memory block on the heap at 0x2512050

Own address on the stack is 0x7ffdf539da00
Managing memory block on the heap at 0x2511c20

resource freed at address 0x2512050
resource freed at address 0x2511c20

让我们看看DeepCopy(DeepCopy &source)

据我了解,

  1. 第1行,为_myInt获取新内存,

  2. 第2行,在第1行获得的内存中分配源的_myInt

所以,我期待这样的结果

resource allocated at address 0x2511c20
Own address on the stack is 0x7ffdf539da00
Managing memory block on the heap at 0x2511c20

resource allocated at address 0x2512020 with _myInt = 42
Own address on the stack is 0x7ffdf539da10
Managing memory block on the heap at 0x2512020

Own address on the stack is 0x7ffdf539da00
Managing memory block on the heap at 0x2512050

resource freed at address 0x2512020
resource freed at address 0x2511c50

因为函数 DeepCopy(DeepCopy &source) 改变的是源的成员地址,而不是目标的

但是,它与上面的实际结果不同。

我误解了什么?

【问题讨论】:

  • 您的赋值运算符有三个问题:首先是内存泄漏,因为您永远不会释放现有内存;其次,在初始化该值之前取消引用_myInt;最后,您不检查自我分配。
  • 未调用赋值运算符。
  • 实际输出是正确的,看来你的预期是错误的。为什么你认为对象应该交换指针?有问题的行 *_myInt = *source._myInt; 正在将 value*source._myInt 复制到 *_myInt
  • 感谢您的评论,我误会了它也​​复制了地址。

标签: c++ deep-copy


【解决方案1】:

source._myInt 指向0x2511c20,在复制之前。那不会改变。 dest1._myInt 指向0x2512050,复制前后。这两个指针不会改变,也不应该改变。

复制存储在这些内存位置的数据,但不复制指针本身。

如果我们为您画出来,也许更容易理解:

首先创建source 对象:

DeepCopy source(42);

它创建了这样的东西:

+---------------+ +----------------+ |来源._myInt | --> | 42 @ 0x2511c20 | +---------------+ +----------------+

然后创建dest1 对象:

DeepCopy dest1(source);

如果我们一步一步地遍历我们首先拥有的复制构造函数

_myInt = (int *)malloc(sizeof(int)); // line 1 

这会让你有

+---------------+ +----------------+ | dest1._myInt | --> | ?? @ 0x2512050 | +---------------+ +----------------+

[此时的值是不确定]

那么你就有了的复制:

*_myInt = *source._myInt;  // line 2

现在你有了

+---------------+ +----------------+ | dest1._myInt | --> | 42 @ 0x2512050 | +---------------+ +----------------+

我们终于回到了main 函数中,你有:

+---------------+ +----------------+ |来源._myInt | --> | 42 @ 0x2511c20 | +---------------+ +----------------+ +---------------+ +----------------+ | dest1._myInt | --> | 42 @ 0x2512050 | +---------------+ +----------------+

您有两个不同的对象,每个对象都有自己独特的_myInt 变量,每个都指向不同的内存位置。这些位置的值恰好相同,但指向这些值的指针不同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    • 2012-04-12
    相关资源
    最近更新 更多