C++ C++;字符串扩展导致分配错误
我必须检查我的应用程序是否存在内存泄漏。然而,一个非常简单的程序已经导致内存泄漏 考虑以下程序为字符串消息分配14个字符:C++ C++;字符串扩展导致分配错误,c++,string,memory,memory-management,memory-leaks,C++,String,Memory,Memory Management,Memory Leaks,我必须检查我的应用程序是否存在内存泄漏。然而,一个非常简单的程序已经导致内存泄漏 考虑以下程序为字符串消息分配14个字符: string Message; int main() { Message = "This is a test"; } 不会导致内存错误 但是,当我尝试初始化长度超过15个字符(比如20个字符)的字符串消息时,会出现内存泄漏错误: string Message; int main() { Message = "This is a test which
string Message;
int main() {
Message = "This is a test";
}
不会导致内存错误
但是,当我尝试初始化长度超过15个字符(比如20个字符)的字符串消息时,会出现内存泄漏错误:
string Message;
int main() {
Message = "This is a test which";
}
导致错误的原因:
Leaks found: 1 allocations (31 bytes)
Ac++,如果初始化一个字符串(它导致最大15个字符+ 0),则C++分配16个字节的空间:
但是,如果我将消息初始化为: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++处理内存分配。< /P> < P>消息是全局变量。< /P> 在构造全局变量之后,但在启动main之前,泄漏检测器必须拍摄内存状态的快照 然后在主要结束之后,但在全局变量被销毁之前,查看内存 string经常(但不总是——依赖于实现)对短字符串进行实现优化。。。但是在堆上分配的字符串长度大于此值
您的泄漏检测器正在查看堆上的字符串,没有意识到消息析构函数(将很快调用)将在短时间内将其释放回堆。消息是一个全局变量 在构造全局变量之后,但在启动main之前,泄漏检测器必须拍摄内存状态的快照 然后在主要结束之后,但在全局变量被销毁之前,查看内存 string经常(但不总是——依赖于实现)对短字符串进行实现优化。。。但是在堆上分配的字符串长度大于此值
泄漏检测器看到堆上的字符串,没有意识到消息析构函数(将很快调用)将在短时间内将其释放回堆。leaker.h头试图通过添加一组
#defines
来截获内存分配:
/* preprocessor magic to override built-in allocation functions with our own */
#define malloc(size) _malloc(size, __FILE__, __func__, __LINE__)
#define calloc(n, size) _calloc(n, size, __FILE__, __func__, __LINE__)
#define free(ptr) _free(ptr, __FILE__, __func__, __LINE__)
#define realloc(ptr, size) _realloc(ptr, size, __func__, __FILE__, __LINE__)
#ifdef __cplusplus
/* hackish solution to the problem of overriding C++ operator new/delete */
extern const char *_leaker_file;
extern const char *_leaker_func;
extern unsigned long _leaker_line;
#define new (_leaker_file=__FILE__, _leaker_func=__func__, \
_leaker_line=__LINE__) && 0 ? NULL : new
#define delete _leaker_file=__FILE__, _leaker_func=__func__, \
_leaker_line=__LINE__, delete
如果我们忘记了明确不允许重新定义诸如new
和delete
之类的关键字,那么只有当std::string
实现的每个部分都定义为内联函数时,这种黑客才有机会工作
如果
std::string
的某些部分在运行时库中实现(这并非不可能),这些定义将不会对那里的预编译代码产生任何影响。然后检测只会是部分的,并且会错过一些分配或解除分配。leaker.h头试图通过添加一组#defines
来拦截内存分配:
/* preprocessor magic to override built-in allocation functions with our own */
#define malloc(size) _malloc(size, __FILE__, __func__, __LINE__)
#define calloc(n, size) _calloc(n, size, __FILE__, __func__, __LINE__)
#define free(ptr) _free(ptr, __FILE__, __func__, __LINE__)
#define realloc(ptr, size) _realloc(ptr, size, __func__, __FILE__, __LINE__)
#ifdef __cplusplus
/* hackish solution to the problem of overriding C++ operator new/delete */
extern const char *_leaker_file;
extern const char *_leaker_func;
extern unsigned long _leaker_line;
#define new (_leaker_file=__FILE__, _leaker_func=__func__, \
_leaker_line=__LINE__) && 0 ? NULL : new
#define delete _leaker_file=__FILE__, _leaker_func=__func__, \
_leaker_line=__LINE__, delete
如果我们忘记了明确不允许重新定义诸如new
和delete
之类的关键字,那么只有当std::string
实现的每个部分都定义为内联函数时,这种黑客才有机会工作
如果
std::string
的某些部分在运行时库中实现(这并非不可能),这些定义将不会对那里的预编译代码产生任何影响。然后检测只会是部分的,并且会错过一些分配或解除分配。此代码没有问题。因此,这似乎是(a)漏洞检测器中的一个bug,(b)C++实现中的一个错误(不太可能),或者(c)一个假阳性。std::String
实现中的小字符串优化(SSO)造成的。。。“不像java和C++那样的新语言,C和C++不自动为你管理内存。”——仅此句子就可以让你了解工具是多么专业可靠。这个代码没有什么错。因此,这似乎是(a)漏洞检测器中的一个bug,(b)C++实现中的一个错误(不太可能),或者(c)一个假阳性。std::String
实现中的小字符串优化(SSO)造成的。。。“不像java和C++那样的新语言,C和C++不自动为你管理内存。”——仅此句子就可以让你了解工具的专业性和可靠性。