std::string.c_str() 或 std::string.data() 返回的指针需要被释放吗?

7
据我所知,当你调用std::string的c_str()/data()方法时(无论是否带有终止的NUL字符),它会创建一个与其内容相同的数组副本。不管怎样,这个对象是否也负责释放这个数组,还是我需要自己来做呢?
简而言之:
std::string hello("content");

const char* Ptr = hello.c_str();

// Use it....

delete[] Ptr;   //// Really ???

我只是希望在内存分配方面保险起见。
5个回答

8

不,你不需要释放ptr指针。

ptr指向一个位于内部位置的不可修改字符串(实际上,这是编译器的实现细节)。


参考:

C++文档

const char* c_str ( ) const;

获取等效的C字符串

生成与字符串对象相同内容的以空字符结尾的字符序列(C字符串),并将其作为指向字符数组的指针返回。

自动附加一个终止的空字符。

返回的数组指向一个内部位置,该位置具有所需存储空间,用于存储此字符序列及其终止的空字符,但不应在程序中修改该数组中的值,并且只能保证在下一次调用字符串对象的非常量成员函数之前保持不变。


到目前为止,我只知道静态和动态内存。我敢打赌,“不可修改的字符串”就在两者之间。 - BeschBesch
3
你说得对,“ptr”指针不需要被释放(事实上也不能被释放)。而且,该指针的性质是由具体实现定义的。然而,这个指针几乎肯定指向自由存储区中的动态内存,而几乎肯定不会指向静态只读内存。 - Robᵩ
@Rob:对于某些STL版本来说,这个语句几乎肯定是错误的(特别是实现小字符串优化的变体)。 - Martin York
如果有的话,这段文字中有哪些部分是从其他地方复制过来的?那些部分必须被*** *** 明确标记 *** **(引用)为此。否则,这就是剽窃。例如,请参阅我们如何处理完全复制且未正确引用的答案(只包含“参考”链接或类似内容)?*。 - Peter Mortensen
@PeterMortensen 我认为这是来自链接的C++文档,但他们重新表述了它。 - dan1st

4

std::string处理这个指针,所以不要释放它。此外,对使用这个指针有两个限制:

  1. 不要修改被这个指针指向的字符串;它是只读的。
  2. 在调用其他std::string方法后,这个指针可能会变得无效。

2

不需要。字符串类的析构函数会处理字符串的销毁,因此当'hello'超出作用域时,它会被释放。


0

std::string类负责在类对象被销毁时释放用于存储字符串字符的内存。因此,如果您执行以下操作:

delete[] Ptr;

hello 对象被销毁之前或之后(离开它所创建的 C++ {} 作用域),你的程序将遇到一个问题,即尝试释放已经被释放的内存块。


0
不仅你不需要释放指针,实际上你不应该这样做。否则,std::string的析构函数将尝试再次释放它,这可能导致根据平台的不同出现各种错误。

它在我的系统上编译时没有崩溃,但你是对的。尽管如此,我认为析构函数将在释放指针之前检查它。 - BeschBesch
1
不是“不应该”,而是“绝不能”。这样做是错误的,在任何情况下都是如此。 - jalf
@Florian:析构函数不会(也不能)“检查指针”。 - jalf
这会导致运行时内存泄漏而不是编译时错误。 - DragonLord

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接