c++ - string.c_str() 需要解除分配吗?

标签 c++ string memory-management heap-memory stack-memory

我的代码经常将 C++ 字符串转换为 CStrings,我想知道如果原始字符串是在堆栈上分配的,CString 是否也会在堆栈上分配?例如:

string s = "Hello world";
char* s2 = s.c_str();

s2 会分配在栈上还是堆上?换句话说,我需要删除 s2 吗?

相反,如果我有这个代码:

string s = new string("Hello, mr. heap...");
char* s2 = s.c_str();

s2 现在会在堆上,因为它的起源在堆上吗?

为了澄清,当我询问 s2 是否在堆上时,我知道指针在堆栈上。我在问它指向的东西是在堆上还是在栈上。

最佳答案

string s = "Hello world";
char* s2 = s.c_str();

Will s2 be allocated on the stack, or in the heap? In other words... Will I need to delete s2?

不,不要 delete s2 !

s2如果上述代码在函数内部,则在堆栈上;如果代码在全局或命名空间范围内,则 s2将在一些静态分配的动态初始化数据段中。无论哪种方式,它都是一个指向字符的指针(在这种情况下,它恰好是 'H' 的文本内容的 ASCIIZ 表示中的第一个 s 字符)。该文本本身位于 s 的任何位置object 感觉就像在构建那个表示。允许实现按照他们喜欢的方式执行此操作,但 std::string 的关键实现选择是它是否提供“短字符串优化”,允许将非常短的字符串直接嵌入到 s对象以及是否 "Hello world"足够短,可以从优化中受益:

  • 如果是,那么 s2将指向 s 内的内存,将按照 s2 的说明进行堆栈或静态分配以上
  • 否则,在 s 内会有一个指向动态分配(自由存储/堆)内存的指针,其中“Hello world\0”内容的地址由.c_str()返回会出现,s2将是该指针值的拷贝。

请注意 c_str()const ,因此要编译您的代码,您需要更改为 const char* s2 = ... .

不得delete s2 s2的数据积分仍由 s 拥有和管理对象,将因任何对非 const 的调用而失效s的方法或通过 s超出范围。

string s = new string("Hello, mr. heap...");
char* s2 = s.c_str();

Will s2 now be on the heap, as its origin was on the heap?

此代码无法编译,如 s不是指针,字符串没有像 string(std::string*) 这样的构造函数.您可以将其更改为:

string* s = new string("Hello, mr. heap...");

...或...

string s = *new string("Hello, mr. heap...");

后者会造成内存泄漏并且没有任何用处,所以让我们假设前者。那么:

char* s2 = s.c_str();

...需要成为...

char* s2 = s->c_str();

Will s2 now be on the heap, as its origin was on the heap?

是的。在所有情况下,特别是如果 s本身在堆上,那么:

  • 即使 s 内有一个短字符串优化缓冲区c_str()产生一个指针,它必须在堆上,否则
  • 如果 s使用指向更多内存的指针来存储文本,该内存也将从堆中分配。

但同样,即使确定 s2指向堆分配的内存,您的代码不需要释放该内存 - 它会在 s 时自动完成被删除:

string* s = new string("Hello, mr. heap...");
const char* s2 = s->c_str();
...use s2 for something...
delete s;   // "destruct" s and deallocate the heap used for it...

当然,通常最好只使用 string s("xyz");除非您需要超出本地范围的生命周期,以及 std::unique_ptr<std::string>std::shared_ptr<std::string>否则。

关于c++ - string.c_str() 需要解除分配吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8843604/

相关文章:

c++ - 为什么在 main() 之前断言会导致语法错误 "error: expected ' )' before numeric constant"?

python - 字符串递归问题

java - 线程永远保留引用

c - 尝试释放字符串时下一个大小无效(快速)

C++:英特尔 SIMD 内在函数类成员的初始化

c++ - 复制到 vector<unsigned char> 中的无类型对象的内容

c++ - 在 C++ 中将数组设置为已初始化的传入数组

sql server 将字符串转换为日期时间

c++ - 将 C++ 字符串与 C 库函数一起使用

Java 内存解释 (SUN JVM)