当分配一个字符串值并稍后通过分配另一个值进行更改时C++如何管理内存?
How is C++ memory managed when a string value is assigned and later changed by assigning another value?
我真的需要了解在以下情况下如何C++管理内存:
案例-1:
string s1 = "ABCD";
s1= "EFGH";
在字符串值"ABCD"的内存中会发生什么?它会自动解除分配吗?还是这里的内存泄漏?
案例2:
char* val = "ABCD";
val = "EFGH";
与案例 1类似,案例 2 与案例 1 有何不同?
案例3:
string s1 = "ABCD";
string s2 = s1;
是否为值为"ABCD"的 s2 分配了单独的内存?还是 s1 和 s2 指向此处的相同内存位置? 在这种情况下,如何管理内存?
请分享一个链接以深入研究这些?任何建议肯定会对我有所帮助。
-
现代
std::string
实现大致遵循这些规则(这里也解释得很好(:- 短字符串(<=26 个字符?(使用称为 SSO 的优化在堆栈上分配。 字符串
- 长度超过堆上分配的字符串。std::string 实现在内部管理此处的分配和解除分配。
-
const char* x = "ABCD"
在静态存储中的堆栈上分配,指向它的指针存储在堆栈上。这可以从此处的CE链接中看到,其中rsp:rsp-8
指向.LC0
。
鉴于上述观察结果:
- 情况 1:它在堆栈上分配 x,然后将新值"EFGH"复制到 s1,而不分配更多的堆栈空间。CE 链接
- 情况 2:它使
val
指向存储"ABCD"的静态存储,然后指向"EFGH"所在的位置。CE 链接
情况 - 3:这将(未启用优化(在堆栈(CE 链路(上分配 2 个 std::string,遵循情况 1。
如注释中所述,替代std::string
实现是可能的,例如 (1( 那些不实现 SSO 的实现 (2( 实现写入时复制。
案例 1
string s1 = "ABCD";
string
处理内存分配以为您存储"ABCD"
。当string
析构函数超出范围时,将自动调用s1
,这将释放string
分配的内存。
s1 = "EFGH";
string
复制赋值运算符将使用"EFGH"
覆盖内存存储"ABCD"
。
案例2
char* val = "ABCD";
val = "EFGH";
Fred Larson 在上面的评论中回答了这个问题,你只是重新分配了一个指向静态字符串的指针。堆栈将仅为指针(而不是数据(分配内存,当指针超出范围时val
将自动释放。
案例3
string s1 = "ABCD";
string s2 = s1;
s2
将分配内存并复制s1
。复制赋值运算符的写入时复制实现只会在s2
发生突变时分配和复制内存。但是,从 C++11 开始,似乎不再允许 COW 实现std::string
(C++11 中 COW std::string 实现的合法性(。
案例4
下面是一个方案示例,在该方案中,您确实需要担心释放分配的内存。
如果需要一个string
来超过创建它的范围,则可以使用它。(在实践中,通常应避免使用此方法。请参阅下面的案例 5。
string* s1 = new string("ABCD");
delete s1;
在此示例中,string
仍在内部管理内存以存储"ABCD"
,但string
指针是堆分配的,并且当s1
超出范围时不会调用string
析构函数。在这种情况下,您负责使用delete
来确保在不再需要内存时清理内存s1
。
案例5
shared_ptr<string> s1 = make_shared<string>("EFGH");
shared_ptr
通常是要走的路,而不是new
和delete
。共享指针可防止由于编程错误而导致的大量内存泄漏。shared_ptr
为您处理delete
,并使用引用计数使string
保持活动状态,直到最后一个引用被销毁。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 使用RAII在给定次数的迭代后重新分配资源