1

我对 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

4 回答 4

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

With these two statements you just caused a memory leak, and abc does not point to dynamic memory anymore but it points to a string literal placed in read only memory. So when you call:

delete [] abc;

You are actually calling delete on a pointer which does not point to dynamically allocated memory, this results in undefined behavior & potentially a segmentation fault.

abc = "abcdef";

does not copy the string to memory allocated to abc but it simply reseats abc to point to a string literal. To be able to copy the string to memory allocated for abc you need to use std::copy or strncpy.

于 2013-08-25T12:33:48.033 回答
3
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 |
                +----------+
于 2013-08-25T12:41:59.140 回答
2

You're not deleting through the pointer you've allocated and your program has undefined behaviour.

abc = "abcdef";

abc now points to the beggining of the string literal of static storage duration. You're not allowed to modify it or delete it. The original pointer, it's lost and you leaked the memory you allocated.

What you could (and what I think you wanted) to do:

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);

Any yes, std::string owns the content of the string, it copies it from abc.

于 2013-08-25T12:33:31.887 回答
1

You didn't allocate the memory pointed to by abc: it is coming from a string literal. Thus, you are not allowed to delete the memory or modify the content in any way. When an std::string is constructed from a string literal, it creates a copy of the string literal and maintains the memory needed for this copy internally.

于 2013-08-25T12:33:16.380 回答