内存泄漏与内存分配

时间:2019-03-22 00:59:01

标签: c++ dynamic memory-leaks

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

<html>
  <body>
    <input id="name" value="Jenna" />
    <input id="address" value="840 9STREET" />
    <input id="postalcode" value="T2P 2T4" />
    <input id="phone" value="111-111-1111" />
    <input id="email" value="Renee@gmail.com" />
    <button id="clickMe">click me</button>
  </body>  
  <script>
    var objectarray = [];
    var button = document.getElementById("clickMe");

    function addToArray() {
      var customerobject = {};
      customerobject.name = document.getElementById("name").value;
      customerobject.address = document.getElementById("address").value;
      customerobject.postalcode = document.getElementById("postalcode").value;
      customerobject.phone = document.getElementById("phone").value;
      customerobject.email = document.getElementById("email").value;
      objectarray.push(customerobject);
      console.log(objectarray);
    }
    button.addEventListener("click", addToArray);
  </script>
</html>

由于des是局部变量,因此将导致内存泄漏,因此他在之后建议了另一种方法。

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

但是我不明白为什么局部变量会导致内存泄漏,第一个和第二个之间有什么区别。 第二个函数不是也使用char* toNormalWord(const std::string& src) { char* des = new char[src.size() + 1]; // stuff return des; } 作为函数中的局部变量吗? 我以为区别只是该函数接收des作为参数或只是创建自己。 我想我不知道重要的事,但是我不知道那是什么...

3 个答案:

答案 0 :(得分:2)

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

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

  

第一个和第二个之间有什么区别

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

返回值时,可以稍后将其删除,从而避免泄漏。

  

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

是的。区别在于是否返回其值。

答案 1 :(得分:0)

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

检查此网站

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

答案 2 :(得分:0)

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<char[]>

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是最佳选择。