分配字符串值并随后通过分配另一个值来更改C ++内存的方式?

问题描述 投票:0回答:2

在以下情况下,我真的需要了解如何使用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指向此处相同的存储位置?在这种情况下如何管理内存?

请分享一个链接,以深入研究这些内容?任何建议绝对会帮助我。
c++ memory-management memory-leaks
2个回答
1
投票
  1. 现代std::string实现大致遵循这些规则(也很好地解释了here:]

      短字符串(<= 26个字符?)使用称为SSO的优化在堆栈上分配。
  2. 比在堆上分配的字符串长的字符串。这里的std :: string实现在内部管理分配和释放。
  3. [const char* x = "ABCD"]在静态存储中分配了[[在堆栈上,并且指向它的指针存储在堆栈中。这可以在CE链接here中看到,其中rsp:rsp-8指向.LC0

鉴于以上观察:

情况1:它在堆栈上分配x,然后将新值“ EFGH”复制到s1,而不分配更多堆栈空间。 CE Link

    情况2:它使val指向存储“ ABCD”的静态存储,然后指向“ EFGH”的静态存储。 CE Link
  • 情况3:这将(不启用优化)在情况1之后,在堆栈上分配2个std :: strings(CE Link)。
  • 如评论中所述,例如,可以选择std::string实现(1)不实现SSO的实现(2)实现写时复制。

  • 0
    投票
    string s1 = "ABCD";

    [string]处理内存分配以为您存储"ABCD"。当string超出范围时,将自动调用s1析构函数,这将释放string分配的内存。
    s1 = "EFGH";
    

    string复制分配运算符将用"ABCD"覆盖存储"EFGH"的存储器。

    案例2

    char* val = "ABCD"; val = "EFGH";

    Fred Larson在上面的评论中回答了这个问题,您只是在重新分配指向静态字符串的指针。堆栈只会为指针分配内存(而不是数据),并且当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

    这里是您

    do

    需要担心释放分配的内存的情况的示例。

    如果需要string来延长其创建范围,则可以使用此选项。 (实际上,通常应该避免这种方法。请参见下面的[[案例5

    。)string* s1 = new string("ABCD"); delete s1;

    在此示例中,string仍在内部管理内存以存储"ABCD",但是string指针是堆分配的,并且当string超出范围时,将不会调用s1析构函数。在这种情况下,您有责任使用delete来确保在不再需要s1时清理内存。

    案例5
    shared_ptr<string> s1 = make_shared<string>("EFGH");
    

    shared_ptr通常是与newdelete相对的方法。共享指针可防止由于编程错误而导致的大量内存泄漏。 shared_ptr为您处理delete,并使用引用计数使string保持活动状态,直到最后一个引用被破坏为止。

    © www.soinside.com 2019 - 2024. All rights reserved.