- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我是这个网站和编程世界的新手。所以,请耐心等待我:)
我阅读了三的规则,并且了解了复制构造函数和赋值运算符的工作原理。所以我了解到,C++ 提供的默认对象提供了对象的浅拷贝(或按成员方式)。
我的问题是......如果类有一个成员指针(指向动态分配的内存),默认的赋值运算符,只会将指针中保存的地址从原始对象复制到对象的指针被分配给。但这不会造成内存泄漏吗?例如下面的代码:
class GCharacter //Game Character
{
private:
std::string name;
int capacity; //the capacity of our tool array
int used; //the nr of elements that we've actually used in that tool array
std::string* toolHolder; //string pointer that will be able to reference our ToolArray;
public:
static const int DEFAULT_CAPACITY = 5;
//Constructor
GCharacter(std::string n = "John", int cap = DEFAULT_CAPACITY)
:name(n), capacity(cap), used(0), toolHolder(new string[cap])
{
}
}
int main()
{ GCharacter gc1("BoB", 5);
GCharacter gc2("Terry", 5);
gc2 = gc1;
GCharacter gc3 = gc1;
return 0;
}
因此,在这段代码中,当创建 gc1 时,gc1.toolHolder 保存一些动态分配的 5 个字符串内存的地址。比方说,地址 125。之后,创建 gc2 并为 5 个字符串动态分配内存,假设 gc2.toolHolder 保存地址 135。
下一行代码调用默认赋值运算符,并提供从 gc1 的每个成员到 gc2 的浅拷贝。这意味着现在指针 gc2.toolHolder 也持有地址 125,我们不能再访问地址 135 处的内存。那么默认赋值运算符,在这种情况下,会造成内存泄漏吗? ...还是我理解有误??
另外,另一个问题,在默认复制构造函数的情况下,因为它只在不存在的对象上调用,这意味着 gc3.toolHolder 将没有机会分配新内存,比方说, 在地址 145?它只会接收存储在 gc1.toolHolder 中的地址吗?
要尝试更具体...我要问的是它是否与上面的情况相同,除了我们只有两个指针 gc3.toolHolder 和 gc1.toolHolder,引用相同的地址 125,没有 gc3.toolHolder动态分配 5 个字符串的新内存。
长话短说,当我们实例化一个有指向动态分配内存的指针成员变量的类时,默认的赋值运算符会不会导致内存泄漏?和默认的复制构造函数共享指向相同分配内存的指针?
感谢您的宝贵时间!
最佳答案
您遇到的内存泄漏是缺少析构函数来释放构造函数中使用new
分配的内存,您需要:
~GCharacter() { delete[] toolHolder; }
如果你添加这个,你会看到你遇到的第二个问题:默认生成的复制构造函数和赋值只是复制/分配指针,因此当你有一个拷贝并且原始和拷贝都超出范围时,它们将两者都试图删除内存。这种双重释放当然是比内存泄漏大得多的问题,因为它很可能会破坏内存。
也就是说,您想添加自己的复制构造函数和赋值运算符并正确实现它。在这种情况下,它意味着为拷贝的 toolHolder
分配内存。通常,阅读有关 Rule of Five
的信息何时为您的类实现哪组方法。
关于c++ - 当浅拷贝指针时,默认的赋值运算符是否会造成内存泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19483022/
我有一个基类和两个派生类,我需要将一个指向派生类对象的指针复制到另一个类中,就像示例一样。 class Base { public: Base(const Base& other); } cl
考虑 Container 类,它主要存储 Box 对象的 unique_ptr vector ,并可以对它们执行一些计算。 class Container { private: std::
引用是指保存的值为对象的地址。在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些。下面举个例子: 问题描述:已知一个列表,求生成一个
我正在尝试实现 Bron-Kerbosch 算法,这是一种用于查找派系的递归算法。我设法达到了一个点,它返回了正确数量的派系,但是当我打印它们时,它们不正确 - 添加了额外的节点。我在这里遗漏了什么明
在评估中,我选择了选项LINE I 上的运行时错误。没有未定义行为这样的选项,尽管我认为这是正确的选择。 我不确定,但我认为评估有误。我编译并运行了该程序,它确实打印了 3, 9, 0, 2, 1,
在函数签名中通过 const 值传递参数是否有任何好处(或相反,成本)? 所以: void foo( size_t nValue ) { // ... 对比 void foo( const s
我为 answer to another question 写了一个 OutputIterator .在这里: #include using namespace std; template clas
我有一个由第三方生成的 dll,它具有某种内部数据结构,将其大小限制为 X 个元素。 所以基本上,它有一个以 X 为限制的队列。 据我所知,DLL 是每个进程的,但是是否可以多次加载 DLL?也许每个
假设我有以下两个数据结构: std::vector all_items; std::set bad_items; all_items vector 包含所有已知项和 bad_items vector
如何在不渲染 CGImage 的情况下从另一个 CIImage 复制一个 CIImage 最佳答案 CIImage *copiedImage = [originalImage copy]; 正如您在
我有一个名为 UINode 的 GUI,我想创建一个拷贝并只更改一些内容。该项目由 3 个基本线程组成。 PingThread、RosThread 和 GuiThread。我试图复制粘贴项目文件夹并将
Qt 新手。如果这个问题太幼稚,请多多包涵。在 Windows 操作系统环境中,我有 Qt 对话框框架应用程序,它具有“重复”- 按钮。在同一目录中,有 Qt 应用程序 - (一个带有关闭按钮的对话框
我正在尝试创建一个函数来复制我的卡片结构。我只需复制 cvalue 即可轻松开始。然而,我的 cvalue 没有复制,当应该读取 1000 时它仍然读取 5。 #include #include
string str1("someString"); string str2 = string(str1);//how many copies are made here //copy2 =
我希望了解 boost::bind 执行何种函数对象的内部拷贝。由于这些对象的构造函数似乎没有被调用,我推测这是一种“非常浅的复制”,所以我引入了动态内存分配来产生一些错误。但是,下面代码的运行时输出
我正在查看 http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c22-make-default-operations-consis
下面的类方法Augmented3dPoint::getWorldPoint()返回对其成员的引用 cv::Point3f world_point; class Augmented3dPoint { p
我需要通过 MyClass2 将用户定义的 lambda 传递给 MyClass1。我想确保只有一步,没有拷贝。下面的代码实现了吗?有没有更好的方法来做到这一点(比如使用编译器完成的隐式移动)? 注意
在我的数据库访问代码中,我想写一个方法: variant_t GetQueryRows (...) 我想这样调用它: const variant_t result = GetQueryRows (..
我有一个包含引用的类,例如: class A { A(B &b) : b(b) {} // constructor B &b; } 有时b必须是只读的,有时是可写的。当我创建一个 const A
我是一名优秀的程序员,十分优秀!