在以下情况下,我真的需要了解如何使用C ++管理内存:
案例1:
string s1 = "ABCD";
s1= "EFGH";
字符串值“ ABCD”在存储器中会发生什么?它会自动释放吗?还是这里的内存泄漏?
案例2:
char* val = "ABCD";
val = "EFGH";
[[类似于Case-1,Case-2与Case-1有何不同?
Case-3:string s1 = "ABCD";
string s2 = s1;
请分享一个链接,以深入研究这些内容?任何建议绝对会帮助我。是否将单独的内存分配给值“ ABCD”的s2?还是s1和s2指向此处相同的存储位置?在这种情况下如何管理内存?
std::string
实现大致遵循这些规则(也很好地解释了here:]const char* x = "ABCD"
]在静态存储中分配了[[在堆栈上,并且指向它的指针存储在堆栈中。这可以在CE链接here中看到,其中rsp:rsp-8
指向.LC0
。鉴于以上观察:
情况1:它在堆栈上分配x,然后将新值“ EFGH”复制到s1,而不分配更多堆栈空间。 CE Link
val
指向存储“ ABCD”的静态存储,然后指向“ EFGH”的静态存储。 CE Linkstd::string
实现(1)不实现SSO的实现(2)实现写时复制。string s1 = "ABCD";
string
]处理内存分配以为您存储"ABCD"
。当string
超出范围时,将自动调用s1
析构函数,这将释放string
分配的内存。s1 = "EFGH";
string
复制分配运算符将用"ABCD"
覆盖存储"EFGH"
的存储器。
案例2
char* val = "ABCD"; val = "EFGH";
val
超出范围时,指针将自动释放。案例3
string s1 = "ABCD"; string s2 = s1;
s2
将分配内存并复制s1
。如果s2
被突变,则复制分配操作符的写入时复制实现将仅分配和复制内存。然而,从C ++ 11开始,似乎不再允许std::string
的COW实现(Legality of COW std::string implementation in C++11)。案例4案例5这里是您
do
需要担心释放分配的内存的情况的示例。如果需要
。)string
来延长其创建范围,则可以使用此选项。 (实际上,通常应该避免这种方法。请参见下面的[[案例5string* s1 = new string("ABCD"); delete s1;
在此示例中,
string
仍在内部管理内存以存储"ABCD"
,但是string
指针是堆分配的,并且当string
超出范围时,将不会调用s1
析构函数。在这种情况下,您有责任使用delete
来确保在不再需要s1
时清理内存。
shared_ptr<string> s1 = make_shared<string>("EFGH");
shared_ptr
通常是与new
和delete
相对的方法。共享指针可防止由于编程错误而导致的大量内存泄漏。 shared_ptr
为您处理delete
,并使用引用计数使string
保持活动状态,直到最后一个引用被破坏为止。