C ++ std :: string内部内存处理

时间:2013-08-25 12:29:47

标签: c++ string memory-leaks

我对std :: string如何处理它的复制(?)内存感到困惑。

当我尝试这样做时:

char* abc = new abc[512];
abc = "abcdef";
std::string tempstr(abc);
tempstr[0] = 'Y';
std::cout << tempstr.c_str() << std::endl;
std::cout << abc << std::endl;

我得到以下输出:

Ybcdef
abcdef

但是如果我尝试释放 new 分配的内存,最后添加它:

delete [] abc;

我收到内存错误(_BLOCK_TYPE_IS_VALID) 现在我的问题是,这怎么可能?字符串似乎复制abc的数据,保持不变,但由于某种原因,我无法删除它。

我问这个,因为我的代码中有以下情况:

char* somestring = new char[1024];
// something happens to somestring here
stack.push_back(somestring); // stack is a vector of strings

我想知道在哪里可以释放由某些字符串分配的内存。

4 个答案:

答案 0 :(得分:5)

char* abc = new abc[512];
abc = "abcdef";

使用这两个语句只会导致内存泄漏,abc不再指向动态内存,但它指向放在只读内存中的字符串文字。所以当你打电话时:

delete [] abc;

您实际上是在指针上调用delete,而该指针未指向动态分配的内存,这会导致未定义的行为&amp;可能是一个分段错误。

abc = "abcdef";

不会将字符串复制到分配给abc的内存中,但它只是重置abc以指向字符串文字。为了能够将字符串复制到为abc分配的内存,您需要使用std::copystrncpy

答案 1 :(得分:2)

您没有通过已分配的指针进行删除,并且您的程序具有未定义的行为。

abc = "abcdef";

abc现在指向静态存储持续时间的字符串文字的开头。您不能修改或删除它。原始指针,它丢失了,你泄漏了你分配的内存。

你能做什么(以及我想你想做什么):

char* abc = new abc[512];
const char* s = "abcdef"; // note the const - assigning a pointer to string literal to 
                          // char* is illegal in C++11
std::copy(s, s+6, abc);

是的,std::string拥有字符串的内容,它从abc复制。

答案 2 :(得分:2)

char* abc = new abc[512];

       +-----------------------+
abs -> | 512 byte memory block |
       +-----------------------+


abc = "abcdef";

       +-----------------------+
       | 512 byte memory block |
       +-----------------------+

       +----------+
abs -> | abcdef\0 |
       +----------+


std::string tempstr(abc);

       +-----------------------+
       | 512 byte memory block |
       +-----------------------+

       +----------+
abs -> | abcdef\0 |
       +----------+

                +----------+
temp.c_str() -> | abcdef\0 |
                +----------+


tempstr[0] = 'Y';

       +-----------------------+
       | 512 byte memory block |
       +-----------------------+

       +----------+
abs -> | abcdef\0 |
       +----------+

                +----------+
temp.c_str() -> | Ybcdef\0 |
                +----------+

答案 3 :(得分:1)

您没有分配abc指向的内存:它来自字符串文字。因此,您不得以任何方式删除内存或修改内容。当从字符串文字构造std::string时,它会创建字符串文字的副本,并在内部维护此副本所需的内存。