Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;字符串扩展导致分配错误_C++_String_Memory_Memory Management_Memory Leaks - Fatal编程技术网

C++ C++;字符串扩展导致分配错误

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

我必须检查我的应用程序是否存在内存泄漏。然而,一个非常简单的程序已经导致内存泄漏

考虑以下程序为字符串消息分配14个字符:

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 < /Cord>类实现可能使用不同的方案根据字符串的长度分配字符串。如果泄漏检测器没有正确处理全局变量销毁,它可能会报告误报。那么,如果我将字符串赋值循环到消息变量,应用程序使用的内存池怎么可能继续增长?看起来泄漏检测器就是不工作。然而,它观察到的差异可能是由于编译器的
std::String
实现中的小字符串优化(SSO)造成的。。。“不像java和C++那样的新语言,C和C++不自动为你管理内存。”——仅此句子就可以让你了解工具是多么专业可靠。这个代码没有什么错。因此,这似乎是(a)漏洞检测器中的一个bug,(b)C++实现中的一个错误(不太可能),或者(c)一个假阳性。 STD::String < /Cord>类实现可能使用不同的方案根据字符串的长度分配字符串。如果泄漏检测器没有正确处理全局变量销毁,它可能会报告误报。那么,如果我将字符串赋值循环到消息变量,应用程序使用的内存池怎么可能继续增长?看起来泄漏检测器就是不工作。然而,它观察到的差异可能是由于编译器的
std::String
实现中的小字符串优化(SSO)造成的。。。“不像java和C++那样的新语言,C和C++不自动为你管理内存。”——仅此句子就可以让你了解工具的专业性和可靠性。