【问题标题】:Memory leaking with memory allocation内存分配导致内存泄漏
【发布时间】:2019-08-12 22:56:13
【问题描述】:

c++ <error: Cannot access memory at address 0x1> ​​​ 关于这个问题,我还有一个问题。 回答者说第一个

des = new char[src.size() + 1];

由于des是局部变量,会导致内存泄漏,所以他马上建议了另一种方法。

char* toNormalWord(const std::string& src)
{
   char* des = new char[src.size() + 1];
   // stuff
   return des;
}

但是我不明白为什么局部变量会导致内存泄漏,第一个和第二个有什么区别。 第二个不也是在函数中使用des作为局部变量吗? 我认为区别只是函数接收des 作为参数或只是创建自己。 我想我不知道一些重要的事情,但我不知道那是什么......

【问题讨论】:

  • 你在哪里打电话给delete []内存?导致内存泄漏的原因是在代码中的某些时候没有使用delete []。采纳链接中给出的答案的建议——使用std::string

标签: c++ dynamic memory-leaks


【解决方案1】:

首先,des 是局部变量,但它是指针变量,您分配 (src.size() + 1) 大小的内存,因此它在进程的堆内存中分配。

查看这个网站

http://www.cplusplus.com/doc/tutorial/dynamic/

【讨论】:

    【解决方案2】:

    要理解句子片段的含义“只会泄漏内存,因为des是一个局部变量”,必须理解上下文。没有明确说明的是,局部变量的值绝不会被复制到其他地方。

    如果值丢失,则分配泄漏。

    第一个和第二个有什么区别。

    当此处分配的值:des = new char[src.size() + 1]; 没有传递到函数外部时,分配将在函数结束时无条件泄漏。

    当返回值时,它可能会在以后被删除,从而避免泄漏。

    第二个不也是用des作为函数中的局部变量吗?

    是的。区别在于它的值是否被返回。

    【讨论】:

      【解决方案3】:

      eerorika answer 是正确的,但可以扩展。

      然后内存在本地分配,然后这个函数的职责是释放它。 如果您退回它,那么您将这个责任推给其他人,这是很危险的。你会在你的函数中遇到同样的问题,但在其他地方:

      char* toNormalWord(const std::string& src);
      
      void processString(const std::string& src)
      {
          char* des = toNormalWord(src);
          /* ... */
          if (c == '\n') throw new std::exception("invalid character!"); //memory leak of `des`!
          /* ... */
          return; //memory leak of `des`!
      }
      

      现在你的内存现在是其他函数的本地内存,它应该在那里是空闲的。

      避免这一切的最好方法可能是使用std::unique_ptr&lt;char[]&gt;

      std::unique_ptr<char[]> toNormalWord(const std::string& src)
      {
          std::unique_ptr<char[]> des(new char[src.size() + 1]);
          /* ... */
          return des;
      }
      
      void processString(const std::string& src)
      {
          std::unique_ptr<char[]> des = toNormalWord(src);
          /* ... */
          if (c == '\n') throw new std::exception("invalid character!"); //no memory leak!
          /* ... */
          return; //no memory leak!
      }
      

      使用此编译器将始终记得释放此内存。

      在这种特定情况下,您可以使用std::string as suggested by barry。在某些情况下,我什至将std::vecotr 用于字符串。这一切都取决于这个“内存”的用途。 std::string 最适合您需要执行大量字符串操作(如连接)时。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-04-21
        • 1970-01-01
        • 2015-07-06
        • 2014-06-07
        • 2013-11-20
        • 2011-10-28
        • 2016-01-18
        • 2012-12-13
        相关资源
        最近更新 更多