【问题标题】:How to properly free a std::string from memory如何从内存中正确释放 std::string
【发布时间】:2011-06-26 03:59:41
【问题描述】:

当我用完后,从堆上分配的内存中删除 std::string 的最佳方法是什么?谢谢!

【问题讨论】:

  • @Ryan Mitchell:1) 这个问题可以通过阅读大多数 C++ 书籍的前两章轻松回答,2) 有数千个完全相同的副本,3) 措辞不佳,不清楚是什么OP想问。
  • 首先 - 是的,我对 C++ 还很陌生,不,我没有使用 C++ 书籍。我正在通过引用 MSDN 库来学习 C++,但找不到任何特定于释放堆上分配的字符串的内容,我不确定使用 DELETE 函数是否是个好主意,或者我是否应该使用 free(&str ) 或其他一些功能。我可以理解为什么它可能会收到反对票,但是我之前尝试过 Google 和 MSDN,但无法找到好的答案,所以我决定在这里发帖,我得到了我正在寻找的答案。
  • @IDWMaster:C++ 不是你通过阅读参考文档学到的语言,我强烈建议你买一本 C++ 书籍并学习它。
  • @IDWMaster:C++在语法上与C和C#相似,但在成语上却没有。
  • @IDWMaster:Get a book。如果我说“我会开这架飞机,我毕竟会开车!他们都有轮子”,你会笑的。您对 C# 或 C 到 C++ 的了解大致相同。您不会通过假装它们具有 1-1 的功能映射来学习一门语言,它们之所以不同是有原因的。表现得像你什么都不知道,那样学习。作为初学者,您是最后一个有权断言您知道自己在做什么的人;你没有。接受我们的建议。

标签: c++ string


【解决方案1】:

std::string 只是一个普通的类1,所以通常的规则适用。

如果你在堆栈上分配std::string 对象,作为全局对象,作为类成员,......你不需要做任何特别的事情,当它们超出范围时,它们的析构函数被调用,它会处理自动释放用于字符串的内存。

int MyUselessFunction()
{
    std::string mystring="Just a string.";
    // ...
    return 42;
    // no need to do anything, mystring goes out of scope and everything is cleaned up automatically
}

您必须做某事的唯一情况是使用new 运算符在堆上分配std::string;在这种情况下,与使用new 分配的任何对象一样,您必须调用delete 来释放它。

int MyUselessFunction()
{
    // for some reason you feel the need to allocate that string on the heap
    std::string * mystring= new std::string("Just a string.");
    // ...
    // deallocate it - notice that in the real world you'd use a smart pointer
    delete mystring;
    return 42;
}

正如示例中所暗示的那样,通常在堆上分配 std::string 是没有意义的,并且,当您需要时,您仍然应该将此类指针封装在智能指针中以避免甚至冒内存泄漏的风险(如果异常,多个返回路径,...)。


  1. 其实std::string定义为

    namespace std
    {
        typedef std::basic_string<char> string;
    };
    

    所以它是 basic_string 类型为 char 的字符的模板类的实例化的同义词(这不会改变答案中的任何内容,但是您必须甚至是迂腐的关于新手问题)。

【讨论】:

  • 在这里我认为 std::string 是模板类 std::basic_string 的类型定义,具有 char 元素类型,而不是普通类。并不是说作为模板类的 typedef(或作为结构或作为原始类型)对自动和动态对象的销毁和释放有任何影响。
  • @Matteo,还是错了。这不是专业化,而是实例化。在新手问题上学究气尤为重要,因为否则新手很容易接受错误的术语。我不在乎它是专业化还是实例化,但是新手可能会认为“专业化== typedef”看起来很合理,但完全错误。
  • @Sergey Tachenov: std::basic_string&lt;char&gt; 是一个专业化,typedef 是它的同义词;因为他说他知道 C,所以我认为typedef 的作用是显而易见的;仍然,再次修复,下次随意执行编辑。
  • @Matteo,看来我也是这里的新手。我一直认为“特化”仅指使用template&lt;&gt; 语法的显式特化或部分显式特化。事实证明并非如此,对于误导性评论,我们深表歉意。
  • @Sergey:严格来说它是模板实例化,但我已经看到了这两个术语(在这种情况下,explicit instantiation 用于您所说的)。
【解决方案2】:
std::string foo("since it's on the stack, it will auto delete out of scope");

或:

std::string* foo = new std::string("allocated on the heap needs explicit destruction")
delete foo;

【讨论】:

    【解决方案3】:

    如果在堆上就使用delete,如果在栈上就什么也不用。

    【讨论】:

      【解决方案4】:
      void foo() {
          string* myString = new string("heap-allocated objects are deleted on 'delete myString;'");
          cout << *myString << endl;
          delete myString;
      }
      

      或者更好的是,尽可能避免使用指针并使用自动变量:

      void foo() {
          string myString("stack-allocated string is automatically deleted when myString goes out of scope");
          cout << myString << endl;
      }
      

      【讨论】:

        【解决方案5】:

        只需将 std::string 视为任何基本类型。

        std::string *str = new std::string("whatever");
        ///code
        delete str;
        

        【讨论】:

          【解决方案6】:

          您可以像对待任何其他班级一样对待std::string。使用new 进行分配,完成后使用delete。 对于 C++11,我不建议在大多数情况下使用 new 和 delete。如果你需要在堆上分配字符串,使用 std::shared_ptr 来包装它:

          std::shared_ptr<std::string> my_string = std::make_shared<std::string>(std::string("My string"));
          

          一旦my_string 的所有副本超出范围,相关的内存将被自动删除。

          【讨论】:

          • std::shared_ptr 的存在是为了在共享所有权语义和自动引用计数上提供优雅的代理,而不是使堆分配更容易。不过,std::unique_ptr 是完全不同的故事。在建议两者之前提及使用两者的含义可能是明智的......
          猜你喜欢
          • 1970-01-01
          • 2020-06-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-09
          • 1970-01-01
          • 2020-03-21
          • 2020-04-12
          相关资源
          最近更新 更多