C++;在分配字符串值并随后通过分配另一个值进行更改时管理内存? 我真的需要理解C++在以下情况下如何管理内存:

C++;在分配字符串值并随后通过分配另一个值进行更改时管理内存? 我真的需要理解C++在以下情况下如何管理内存:,c++,memory-management,memory-leaks,C++,Memory Management,Memory Leaks,案例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在这里指向同一个内存位置? 在这种情况下如何管理内存? 请分享一个链接来深入研

案例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
    实现大致遵循以下规则(也有很好的解释):

    • 短线(
    • 现代
      std::string
      实现大致遵循以下规则(也有很好的解释):

      • 短字符串(案例1)
        string
        处理内存分配以为您存储
        “ABCD”
        。当
        s1
        超出范围时,将自动调用
        string
        析构函数,这将释放
        string
        分配的内存

        s1 = "EFGH";
        
        字符串
        复制分配运算符将用
        EFGH“
        覆盖存储
        ABCD”
        的内存

        案例2 Fred Larson在上面的评论中回答了这个问题,您只是重新分配了一个指向静态字符串的指针。堆栈将只为指针(而不是数据)分配内存,当
        val
        超出范围时,指针将自动解除分配

        案例3
        s2
        将分配内存并复制
        s1
        。如果
        s2
        发生变异,则copy赋值运算符的copy-on-write实现只会分配和复制内存。但是,从C++11开始,似乎不再允许
        std::string
        的COW实现()

        案例4 下面是一个场景示例,您确实需要担心释放分配的内存

        如果您需要一个
        字符串
        ,以使其在创建该字符串的范围内生存,则可以使用此方法。(在实践中,通常应避免使用此方法。请参阅下面的案例5

        在本例中,
        string
        仍在内部管理内存以存储
        “ABCD”
        ,但
        字符串
        指针是堆分配的,当
        s1
        超出范围时,将不会调用
        字符串
        析构函数。在这种情况下,您负责使用
        删除
        ,以确保不再需要
        s1
        时清理内存

        案例5
        shared_ptr s1=make_shared(“EFGH”);
        
        shared_ptr
        通常是相对于
        new
        delete
        的方法。共享指针可以防止由于编程错误而导致大量内存泄漏。
        shared_ptr
        为您处理
        delete
        ,并使用引用计数使
        字符串保持活动状态,直到最后一个引用被销毁

        案例1
        string
        处理内存分配以为您存储
        “ABCD”
        。当
        s1
        超出范围时,将自动调用
        string
        析构函数,这将释放
        string
        分配的内存

        s1 = "EFGH";
        
        字符串
        复制分配运算符将用
        EFGH“
        覆盖存储
        ABCD”
        的内存

        案例2 Fred Larson在上面的评论中回答了这个问题,您只是重新分配了一个指向静态字符串的指针。堆栈将只为指针(而不是数据)分配内存,当
        val
        超出范围时,指针将自动解除分配

        案例3
        s2
        将分配内存并复制
        s1
        。如果
        s2
        发生变异,则copy赋值运算符的copy-on-write实现只会分配和复制内存。但是,从C++11开始,似乎不再允许
        std::string
        的COW实现()

        案例4 下面是一个场景示例,您确实需要担心释放分配的内存

        如果您需要一个
        字符串
        ,以使其在创建该字符串的范围内生存,则可以使用此方法。(在实践中,通常应避免使用此方法。请参阅下面的案例5

        在本例中,
        string
        仍在内部管理内存以存储
        “ABCD”
        ,但
        字符串
        指针是堆分配的,当
        s1
        超出范围时,将不会调用
        字符串
        析构函数。在这种情况下,您负责使用
        删除
        ,以确保不再需要
        s1
        时清理内存

        案例5
        shared_ptr s1=make_shared(“EFGH”);
        

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

        请共享一个链接以深入研究这些问题?--这些示例都不会泄漏内存。或者s1和s2是否指向相同的内存位置?--如果
        s2
        更改了值会怎么样?
        s1
        是否也会更改?这是你要问的吗?@PaulMcKenzie听起来像这样,并没有那么奇怪。这是写时复制,就是这样Qt字符串的工作原理。编辑:结果是一堆Qt对象使用它。使用
        std::string
        的一个重要原因是您不需要担心内存管理。实际发生的是标准中没有指定的实现细节。
        char*
        示例只是从一个静态st重新分配指针挂断另一个,这样就不用担心内存管理了
        char* val = "ABCD";
        val = "EFGH";
        
        string s1 = "ABCD";
        string s2 = s1;
        
        string* s1 = new string("ABCD");
        delete s1;
        
        shared_ptr<string> s1 = make_shared<string>("EFGH");