c++ 如何正确地从内存中释放std::string

tcbh2hod  于 2023-03-20  发布在  其他
关注(0)|答案(8)|浏览(589)

当我用完std::string后,从堆上分配的内存中删除它的最佳方法是什么?谢谢!

sulc1iza

sulc1iza1#

std::string只是一个普通的class 1,因此适用通常的规则。
如果你在堆栈上分配std::string对象,作为全局变量,作为类成员,...你不需要做任何特殊的事情,当它们超出作用域时,它们的析构函数被调用,它负责自动释放字符串使用的内存。

int MyUselessFunction()
{
    std::string mystring="Just a string.";
    // ...
    return 42;
    // no need to do anything, mystring goes out of scope and everything is cleaned up automatically
}

唯一需要做点什么的情况是使用new操作符在堆上分配std::string;在这种情况下,与使用new分配任何对象一样,必须调用delete来释放它。

int MyUselessFunction()
{
    // for some reason you feel the need to allocate that string on the heap
    std::string * mystring= new std::string("Just a string.");
    // ...
    // deallocate it - notice that in the real world you'd use a smart pointer
    delete mystring;
    return 42;
}

正如示例中所暗示的,通常在堆上分配std::string是没有意义的,并且,当您需要时,您仍然应该将这样的指针封装在智能指针中,以避免内存泄漏的风险(在异常、多个返回路径等情况下)。
1.实际上std::string的定义为

namespace std
{
    typedef std::basic_string<char> string;
};

因此它是char类型字符的basic_string模板类示例化的同义词(这不会改变答案中的任何内容,但在SO上,即使在新手问题上,您也必须迂腐)。

06odsfpq

06odsfpq2#

std::string foo("since it's on the stack, it will auto delete out of scope");

或:

std::string* foo = new std::string("allocated on the heap needs explicit destruction")
delete foo;
2sbarzqh

2sbarzqh3#

如果在堆上,则使用delete,如果在堆栈上,则什么也不用做。

wbrvyc0a

wbrvyc0a4#

void foo() {
    string* myString = new string("heap-allocated objects are deleted on 'delete myString;'");
    cout << *myString << endl;
    delete myString;
}

或者更好的是,尽可能避免使用指针,使用自动变量:

void foo() {
    string myString("stack-allocated string is automatically deleted when myString goes out of scope");
    cout << myString << endl;
}
7uzetpgm

7uzetpgm5#

只需将std::string视为任何基本类型即可。

std::string *str = new std::string("whatever");
///code
delete str;
ftf50wuq

ftf50wuq6#

也许你真的在处理释放内部字符串缓冲区的问题?
出于性能原因,大多数实现保持内部缓冲区分配,即使字符串是“空的”。小字符串(小于sizeof(ptr))直接存储在保存指针的区域中。在字符串的生命周期内,这些字节永远不能被回收。
释放内部构件:经典的技巧是在一个作用域中使用swap。这将强制缓冲区真正释放(也适用于vector/map/ostream/stringstream等):

string s;                                               // size==0 and capacity==15 as the default proxy of the container (help perf on small string)
s = "Looooooooooooooooooooooooooooooong String";        // size==41 and capacity==47 bytes allocated
s.clear();                                              // size==0  BUT capacity==47 bytes STILL allocated!!
        
s = "Looooooooooooooooooooooooooooooong String";        // size==41 and capacity reuse 47 bytes still allocated. 
s.resize(0);                                            // size==0  BUT capacity==47 bytes STILL allocated!!
// swap with scope to force freeing string internals
{ 
    string o;
    o.swap(s);
}                                                       // size==0 AND capacity==15 (back to smallest footprint possible)
s = "12345";                                            // size==5 AND capacity==15 (the string is IN the container, no new alloc)
oxf4rvwz

oxf4rvwz7#

如果你想清除内部std::string的分配,你需要有以下内容:

std::string str;

// fill str with 250 chars

str.clear(); // clears the content: size = 0, capacity = 250
str.shrink_to_fit(); // shrinks the capacity: size = 0, capacity = 16 or 22 (depends on implementation)
wqnecbli

wqnecbli8#

你可以像对待其他类一样对待std::string。使用new来分配,一旦你完成了它,使用delete。对于C++11,我不推荐在大多数情况下使用newdelete。如果你需要在堆上分配字符串,使用std::shared_ptr来 Package 它:

std::shared_ptr<std::string> my_string = std::make_shared<std::string>(std::string("My string"));

一旦my_string的所有副本都超出范围,关联的内存将被自动删除。

相关问题