这里是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
,如果此代码导致内存泄漏,那么说这不是我的“错误”是否合理?
编辑:我想也许我的意思是复制赋值运算符而不是复制构造函数。
答案 0 :(得分:1)
理论上这可能是内存泄漏。但是,无论何时编写内部管理任何类型资源的类(我们经常这样做),始终要尊重The Rule of Five和RAII。我的意思是,如果编写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以便更好地处理所有权。