方法增强C ++代码以完全消除内存泄漏 [英] Ways enhance C++ code to completely remove memory leaks

查看:77
本文介绍了方法增强C ++代码以完全消除内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我可以尝试使用现有代码将内存完全恢复到操作系统的哪些类型的内容?就目前而言,堆中仍有8个字节的内存。另外,当我通过Valgrind运行我的代码时出现这些错误:



What type of things can I try to do with my existing code to fully return back memory to the operating system? Right as it stands there are 8 bytes of memory still in the heap. In addition, I am getting these errors when I run my code through Valgrind:

#ifndef LINKEDLIST
    #define LINKEDLIST  
    /** LinkedList Class Interface
    */
  //begining update  
 class CLinkedlist {
    private:
    struct node {
        node() : mData(0), mNext(nullptr) {}
        int mData;
        node* mNext;
	};
    typedef node *nodePtr;
        
    nodePtr mHead;
    // As already suggested these should be local variables
    nodePtr mCurr;
    nodePtr mTemp;
	public:
    CLinkedlist() : mHead(nullptr), mCurr(nullptr), mTemp(nullptr) {}
    /// end of update
    ~CLinkedlist();
    
        void AddNode( int);
        void DeleteNode( int );
        void Printlist();
    
    };
    
    #endif

    /** \file Linkedlist.cpp
    */

   
    /** Linkedlist Deconstructor
    */
    CLinkedlist::~CLinkedlist(){
      mCurr = mHead;
      mTemp = mHead;
      while (mCurr)
      {
    	mTemp = mCurr;
        mCurr = mCurr->mNext;
        cout << mTemp->mData << " was destroyed." <<endl;
        delete mTemp;
     
      }
      mHead = nullptr;
    }
    
    void CLinkedlist::AddNode( int datanode){
      nodePtr data = new node;
      data->mData = datanode;
    
      if (mHead)
      {
        /// starting from the head, walking down the list
        mCurr = mHead;
        while(mCurr->mNext != nullptr) {
          mCurr = mCurr->mNext;
        }
        mCurr->mNext = data;
      }
    
      else
      {
        mHead = data;
      }
    
    }
    
    void CLinkedlist:: DeleteNode(int deldata){
      nodePtr delptr = nullptr;
      mTemp = mHead;
      mCurr = mHead;
      /// The program either walked the entire list and found
      /// nothing or we found our data
      while (mCurr != nullptr && mCurr->mData !=deldata ){
        mTemp =mCurr;
        mCurr = mCurr->mNext;
      }
      if (!mCurr){
        cout << deldata << " was not in the list\n";
        delete delptr;
      }
      else {
        /// new code
        if (mHead == mCurr)
           mHead = nullptr;
        /// old code
        delptr = mCurr;
        mCurr = mCurr->mNext;
        mTemp ->mNext=mCurr;
        delete delptr;
        cout << "The value "<< deldata << " was deleted\n";
      }
    }
    /** Displays information about our current list
    */
    void CLinkedlist::Printlist(){
      mCurr = mHead;
      while (mCurr)
      {
        cout << mCurr->mData << " -> " << endl;
        mCurr = mCurr->mNext;
      }
    }

    /** 
     * \file main.cpp
     */
    #include <cstdlib>
    #include "Linklist.h"
    
    using namespace std;
    
    int main (){
      CLinkedlist John;
    
      John.AddNode(3);
      //John.DeleteNode(3);
      //John.AddNode(5);
      //John.AddNode(7);
      //John.Printlist();
    
    }





除此之外,我在Valgrind上遇到了各种错误,如下所示。基于未初始化的值





On top of that, I am getting various errors on Valgrind like the ones below. Based on uninitialised values

=24530== Use of uninitialised value of size 4
==24530==    at 0x4AFB934: free_mem (in /lib/arm-linux-gnueabihf/libc-2.19.so)
==24530==    by 0x4AFB3C3: __libc_freeres (in /lib/arm-linux-gnueabihf/libc-2.19.so)
==24530==    by 0x4023633: _vgnU_freeres (vg_preloaded.c:61)
==24530==    by 0x48C5ED7: std::ctype<char>::_M_widen_init() const (in /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.20)
==24530== 
==24530== Conditional jump or move depends on uninitialised value(s)
==24530==    at 0x4AFB9B0: free_mem (in /lib/arm-linux-gnueabihf/libc-2.19.so)
==24530==    by 0x4AFB3C3: __libc_freeres (in /lib/arm-linux-gnueabihf/libc-2.19.so)
==24530==    by 0x4023633: _vgnU_freeres (vg_preloaded.c:61)
==24530==    by 0x48C5ED7: std::ctype<char>::_M_widen_init() const (in /usr/lib/arm-linux-gnueabihf/libstdc++.so.6.0.20)
==24530== 
==24530== 
==24530== HEAP SUMMARY:
==24530==     in use at exit: 8 bytes in 1 blocks
==24530==   total heap usage: 1 allocs, 0 frees, 8 bytes allocated
==24530== 
==24530== LEAK SUMMARY:
==24530==    definitely lost: 0 bytes in 0 blocks
==24530==    indirectly lost: 0 bytes in 0 blocks
==24530==      possibly lost: 0 bytes in 0 blocks
==24530==    still reachable: 8 bytes in 1 blocks
==24530==         suppressed: 0 bytes in 0 blocks



我可以尝试使用现有代码完全将内存返回给操作系统吗?

出于测试目的,我在Linux操作系统上使用了Blueberry Pi。另外,我使用了g ++编译器,如果有帮助,还包括-std = c ++ 11标志。



我尝试过:



我已经对我的内存泄漏进行了彻底的研究,但我找到的东西都是通过c编程的,或者不适用于我的情况。我发现我可能遇到的一个问题是我没有初始化我的值,这就是我收到这些错误的原因。但是,仔细检查后,我会初始化我的所有类声明。我能够将问题追溯到我的析构函数,显然,它并没有正确地释放内存。但是,这可能是一个更深层次的问题。在main中调用时,我的DeleteNode()方法能够释放内存,但我不知道它是如何或为什么这样做而不是我的析构函数。



更新

我尝试了在这个论坛上提出的各种方法,但遗憾的是,这不起作用。我连接到各种Raspberry Pies,包括Blueberry,raspberry和pennutbutter,以便在我的虚拟Linux机器上进行测试,但每当我使用Valgrind测试我的应用程序时,除了我已经显示的错误消息之外,我还会收到非法指令,(不是示出)。另外,我使用了Putty,但它有同样的效果。但是,我有点放弃,Visual Studio它没有报告我有任何泄漏,你们也不是所以我真的不知道你们似乎没有发现我如何处理内存分配有什么问题和deallocation,所以我不知道。


What type of things can I try to do with my existing code to fully return back memory to the operating system?
For testing purposes, I used a Blueberry Pi on a Linux operating system. In addition, I used a g++ compiler and included -std=c++11 flags if that helps.

What I have tried:

I have done thorough research on my deciphering my memory leaks, but either the things I found was programmed through c or not applicable in my situation. One of the issues I found that I potentially was I didn't initialize my values which are why I was getting those errors. However, after careful inspection, I initialize all my in my class declarations. I was able to trace the problem to my destructor, apparently, it isn't deallocating the memory properly. However, it could be a deeper issue. My DeleteNode () method when called in the main, is able to deallocate the memory, but I don't how or why it can do that but not my destructor.

Update
I tried various methods suggested on this forum, but unfortunately, that didn't work. I connected to various Raspberry Pies, including Blueberry, raspberry, and pennutbutter to test on my virtual Linux machine but whenever I use Valgrind to test my application, in addition to the error message that I already showed I also get an illegal instruction,(not shown). Also, I used Putty, but it had the same effect. However, I have sort of given up, Visual Studio it doesn't report I have any leaks and neither do you guys so I honestly don't know and you guys don't seem to find anything wrong with how I handle the memory allocation and deallocation, so I don't know.

推荐答案

看起来这是一个编译器/平台/ LIBC相关的问题。如前所述,我已经测试了代码(Ubuntu 14.04.05 LTS 32位,GCC 4.8.4)并且没有内存泄漏。



消息使用未初始化的值4可能表示存在一个unitialised值(指针传递给 free_mem )。



为了安全起见,我建议使用构造函数初始化成员变量。我不确定你的方法是否确保成员总是被初始化。

It looks like this is a compiler / platform / LIBC dependant problem. As already noted I have tested the code (Ubuntu 14.04.05 LTS 32 bit, GCC 4.8.4) and had no memory leak.

The message "Use of uninitialised value of size 4" may indicate that there is an unitialised value (a pointer passed to free_mem).

To be on the safe side I suggest to use the constructors to initialise member variables. I'm not sure if your method ensures that the members are always initialised.
class CLinkedlist {
private:
    struct node {
        node() : mData(0), mNext(nullptr) {}
        int mData;
        node* mNext;
    };
    typedef node *nodePtr;
        
    nodePtr mHead;
    // As already suggested these should be local variables
    nodePtr mCurr;
    nodePtr mTemp;
public:
    CLinkedlist() : mHead(nullptr), mCurr(nullptr), mTemp(nullptr) {}
    // ...
};


这篇关于方法增强C ++代码以完全消除内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆