【发布时间】:2017-11-25 15:43:15
【问题描述】:
我有一个memory leaking library 来检查我的应用程序是否存在内存泄漏。但是,一个非常简单的程序已经导致内存泄漏。
考虑以下将 14 个字符分配给字符串 Message 的程序:
string Message;
int main() {
Message = "This is a test";
}
不会导致内存错误。
但是,当我尝试初始化长度超过 15 个字符(比如说 20 个)的字符串 Message 时,它给了我一个内存泄漏错误:
string Message;
int main() {
Message = "This is a test which";
}
导致错误:
Leaks found: 1 allocations (31 bytes)
显然,如果您初始化一个字符串(最多 15 个字符 + \0),c++ 将分配 16 个字节的空间:
string Message;
但是,如果我将消息初始化为:
string Message = "This is a test which is long enough to hold 'This is a test which'";
之前的内存泄漏错误消失了。
所以,当我尝试使用超出字符串缓冲区实际声明大小的动态字符串大小时,C++ 不能很好地分配内存?
可视化:
string Message; //Allocates 16 bytes of memory whereof the 16th position is \0
Message = "This is a test which"; //longer then 15 --> Memory Leak
但是,如果我执行以下操作,它不会产生任何错误:
string Message = "This is a test which can hold a long string";
Message = "This is a test which"; //NO ERRORS
如何在 C++ 中解决这个问题?我更喜欢坚持使用字符串,但是我需要知道如何正确扩展字符串。因此,如果字符串内容溢出先前分配的内存,则让 C++ 处理内存分配。
【问题讨论】:
-
这段代码没有问题。因此,这似乎是 (a) 泄漏检测器中的错误,(b) C++ 实现中的错误(不太可能),或 (c) 误报。
-
std::string类实现可能会根据字符串的长度使用不同的方案为字符串分配内存。如果泄漏检测器没有正确处理全局变量破坏,它可能会报告误报。 -
那么,如果我循环将字符串分配给消息变量,应用程序使用的内存池怎么可能不断增长?
-
看起来您的检漏仪无法正常工作。尽管如此,它确实观察到的差异可能是由于编译器的
std::string实现中的小字符串优化 (SSO)。 -
顺便说一句... “与 Java 和 C# 等较新的语言不同,C 和 C++ 不会自动为您管理内存。” - 这句话本身就应该给出您了解该工具的专业性和可靠性。
标签: c++ string memory memory-management memory-leaks