【问题标题】:C++ - Shallow copying a pointer. Why is this code working?C++ - 浅拷贝指针。为什么这段代码有效?
【发布时间】:2016-04-18 22:51:18
【问题描述】:

根据我对主题的理解: 浅拷贝是将对象的非指针类型复制到另一个对象。当一个对象有指针时,不能进行浅拷贝,因为被复制的对象将获得该指针的地址,当两个对象中的任何一个被删除时,另一个将悬空,因为它们指向相同的位置在记忆中。 当涉及指针时使用深拷贝,因为它保留了与原始对象空间分开的空间,并且只是将内容从一个内存位置复制到另一个内存位置。这样,当其中一个对象被删除时,另一个对象就不会悬空。 也就是说,我想知道为什么这个程序能正常工作,即使我已经做了一个指针的浅拷贝

struct aStruct {
    int *i;
    aStruct(int *p) : i(p) {
        cout << "Created aStruct" << endl;
    }
    aStruct(const aStruct &s) {
        cout << "Copying aStruct" << endl;
        i = s.i;
    }
    aStruct &operator=(const aStruct &s) {
        cout << "Assigning aStruct" << endl;
        i = s.i;
        return *this;
    }
};

int main() {
    int *x = new int(3);
    aStruct s1(x);
    aStruct s2 = s1;
    int *y = new int(4);
    aStruct s3(y);
    s3 = s1;
}

s1、s2 和 s3 都有它们的变量 i 指向同一个地方。因此,当到达 main() 函数的末尾并且其中一个被破坏时,其他的不应该悬空导致错误吗?我的程序运行良好。有人可以向我解释一下吗?

谢谢大家

【问题讨论】:

  • 没有任何问题,因为您从不删除任何内容。
  • 当结构被销毁时,它不会对它指向的项目做任何事情,因为你没有写析构函数,也没有使用智能指针。
  • 您的代码泄漏内存(技术上)。
  • 但我认为在代码块的末尾调用默认的析构函数来删除所有指针。不对吗?
  • 默认的析构函数是破坏对象本身,其中的“对象”是一个指针。它对指向的数据做任何事情。此外,虽然您的对象实际上是微不足道的,所以实际上,这里不需要实际的析构函数。

标签: c++ pointers deep-copy shallow-copy


【解决方案1】:

您正在复制指针,而不是数据。这里的每个对象本身就是一个对象,此外,您似乎认为 C++ 是垃圾收集的。它不是(除了一些不常见的实现)

您的程序基本上会泄漏内存,并且仅通过操作系统释放您的进程在终止后消耗的任何内容才能进行清理。因此,在应用程序的整个生命周期内,您的所有指针都指向完全有效的内存。

【讨论】:

  • 如果 OP 假设 C++ 被垃圾回收,那么假设存在悬空指针是没有意义的。我认为 OP 假设当一个指针被销毁时,它的指向对象也被销毁。当然不是这样。
【解决方案2】:

不幸的是,C++ 中没有 Deep 和 Shallow 指针的概念。 Java 和 C# 中的引用概念与 C++ 中的指针不同。 你应该继续阅读

这样一来,在 C++ 中,指针指的是它所在内存位置中的任何对象,指针所指向的位置。

所以,你正在做的是将分配的位置复制到你的构造函数到对象中......当析构函数运行时,整个对象从内存中释放(死),包括指针int* i 这是一个数据成员。但是new 分配的内存位置直到有人用delete 调用同一位置时才被释放。

【讨论】:

  • 如果您忽略此答案的其余部分,并且这样做是愚蠢的,请阅读三法则上的链接。
猜你喜欢
  • 2010-12-11
  • 2010-09-16
  • 1970-01-01
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-21
相关资源
最近更新 更多