从内存泄漏中返回一个C++ std :: string对象是否安全?

Ste*_*hen 12 c++ string memory-leaks std

我对C++的字符串相当新手,所以下面的模式可能有点难看.在开始使用更大的系统进行集成测试之前,我正在查看我编写的一些代码.我想知道的是它是否安全,或者是否容易泄漏内存?

string somefunc( void ) {
    string returnString;
    returnString.assign( "A string" );
    return returnString;
}

void anotherfunc( void ) {
    string myString;
    myString.assign( somefunc() );
    // ...
    return;
}
Run Code Online (Sandbox Code Playgroud)

我的理解是,returnString的值被分配给一个新对象myString,然后在解析对somefunc的调用时销毁returnString对象.在myString超出范围的某个时候,它也会被破坏.

我通常会将指向myString的指针传递给somefunc()并直接分配给myString的值,但我正在努力使我的代码更清晰(并且更少依赖副作用函数样式).

Pét*_*rök 10

是的,以string这种方式返回(按值)是安全的,虽然我更喜欢这样分配:

string myString = somefunc();
Run Code Online (Sandbox Code Playgroud)

这更容易阅读,并且也更有效(保存空字符串的构造,然后将被下一次调用覆盖assign).

std::string 管理自己的内存,它有正确编写的复制构造函数和赋值运算符,因此以这种方式使用字符串是安全的.


Dou*_* T. 7

是的,这样做

   return returnString
Run Code Online (Sandbox Code Playgroud)

您正在调用字符串的复制构造函数.它将returnString的副本*执行到临时(也就是rValue)中,取代了调用表达式中的"somefunc()":

   myString.assign( somefunc() /*somefunc()'s return becomes temporary*/);
Run Code Online (Sandbox Code Playgroud)

这又被传递给assign并由assign用来执行myString的复制.

因此,在您的情况下,string的复制构造函数保证深层复制并确保没有内存泄漏.

*请注意,这可能是也可能不是真正的深层副本,复制构造函数的行为是特定于实现的.一些字符串库实现了写时复制,它具有一些内部簿记,以防止在实际需要之前进行复制.


Wya*_*son 5

你是完全安全的,因为你按字符串返回字符串,字符串将被"复制",而不是通过引用.如果你要返回a std::string &,那么你做错了,因为你有一个悬空参考.有些编译器甚至可以执行返回值优化,甚至在返回时也不会真正复制字符串.有关更多信息,请参阅此帖子.