分配到解除引用的字符串 - 这会导致内存泄漏吗?

时间:2016-11-13 22:59:21

标签: c++ memory-management memory-leaks

这里是C ++的新手。以下是否会导致内存泄漏?

// debug is optional, for debugging purposes.
// Say my_string is an internal string class my company uses.

int DoSomething(my_string *debug) {
  const my_string& s = GetString();
  if (debug != nullptr) *debug = s;  // Could this cause a memory leak?
  return DoSomethingElse(s);
}

我想在这里检查一下我的理解:我认为在注释行中debug所指向的内存区域将被s的内容(副本)覆盖,除非那里是my_string实现的复制构造函数,在这种情况下它也可以执行其他一些操作。

如果没有my_string的特殊拷贝构造函数,那么如果my_string指向其内部表示中的任何动态分配的内存(它可能会执行,因为它可以保存任意长度的字符串) ,那么上面的代码会导致内存泄漏。

另外,关于预期的C ++“礼仪”的另一个问题我想 - 我应该能够假设编写my_string的人写了一个复制构造函数来避免这种情况下的内存泄漏吗?也就是说,由于我自己的代码中没有任何new,如果此代码导致内存泄漏,那么说这不是我的“错误”是否合理?

编辑:我想也许我的意思是复制赋值运算符而不是复制构造函数。

3 个答案:

答案 0 :(得分:1)

理论上这可能是内存泄漏。但是,无论何时编写内部管理任何类型资源的类(我们经常这样做),始终要尊重The Rule of FiveRAII。我的意思是,如果编写my_string类的人理智,他们明确定义了复制操作符,以免泄漏。

此外,如果您不完全理解复制构造函数和复制操作符之间的区别,this question可能会有所帮助。

答案 1 :(得分:0)

答案完全取决于my_string operator=(const my_string& s)的作用。如果它们引用您创建的本地临时字符串所拥有的内存,那就是它们的错误。如果你知道的话,还有你的。在那种情况下,它可能会崩溃。

另一方面,如果他们对您传递给operator=的字符串进行深层复制,那么一切都很顺利,当您的本地字符串超出范围时,它就可以了。

您不应该担心内存泄漏,而是担心字符串debug中可能存在悬空指针。

答案 2 :(得分:-2)

是的,你的错,使用你知道不好的坏代码总是你的错。修复它或使用大量注释解决它,但从不假装其他人的问题。

代码不泄漏,但可能会崩溃。

当您返回指向字符串的指针时会发生什么,但是当您离开该函数时,将删除原始字符串内存。现在通常内存在短时间内保持不变,但迟早(通常更早)其他东西将使用字符串过去占用的内存,最多会出现垃圾,最坏情况下崩溃。

你会注意到从GetString返回的my_string可能会创建一个临时副本(你没有显示代码)所以s会指向这个临时对象。如果GetString返回一个指向原始字符串的指针,那么你就处于更安全的状态,但现在你可以使用GetString返回的原始字符串。

返回一个被复制的字符串对象并返回该副本(编译器将对此进行优化,以便获得最少的内存副本)或返回shared_ptr以便更好地处理所有权。