Queue与UniqueQueue类内存泄漏问题排查求助
C++内存泄漏排查求助
本人共有5个C++文件,目前出现内存泄漏错误,确定问题源于提供的Queue.h和UniqueQueue.h文件,但不确定泄漏仅存在于其中一个还是两者均存在。现附上这两个文件的代码以及Valgrind检测得到的内存泄漏报告,请求协助排查并解决该问题。
Queue.h
#ifndef SDDS_QUEUE_H__ #define SDDS_QUEUE_H__ #include <iostream> #include <cstdlib> #include "Dictionary.h" //using namespace std; namespace sdds{ template<typename T, unsigned int CAPACITY> class Queue{ T* m_array[CAPACITY]; unsigned int m_size; public: Queue() : m_size{0} {} //Modify the push() member function in the Queue module to enable inclusion polymorphism on the hierarchy. For the same purpose, add an empty body destructor. virtual bool push(const T& item){ if(m_size < CAPACITY){ m_array[m_size] = new T(item); m_size++; return true; } return false; } //Specialize the class-member object when type T = Dictionary and CAPACITY = 100u so the term is "Empty Term" and the definition is "Empty Substitute". // bool push(const T& item){ // if(m_size < CAPACITY){ // m_array[m_size++] = new T(item); // return true; // } // return false; // } T pop(){ T temp = *m_array[0]; for(unsigned int i = 0; i < m_size - 1; i++){ m_array[i] = m_array[i + 1]; } m_size--; return temp; } unsigned int size() const{ return m_size; } void display(std::ostream& os = std::cout) const{ //print something like this /* ---------------------- | Dictionary Content | ---------------------- */ os << "----------------------" << std::endl; os << "| Dictionary Content |" << std::endl; os << "----------------------" << std::endl; for(unsigned int i = 0; i < m_size; i++){ os << *m_array[i] << std::endl; } os << "----------------------" << std::endl; } T operator[](unsigned int index) const{ if(index < m_size){ return *m_array[index]; } return T(); } //deallocation virtual ~Queue(){ for(unsigned int i = 0; i < m_size; i++){ delete m_array[i]; } } }; } #endif
UniqueQueue.h
#ifndef SDDS_UNIQUEQUEUE_H__ #define SDDS_UNIQUEQUEUE_H__ #include <iostream> #include <cstdlib> #include <bits/stdc++.h> #include "Queue.h" #include "Dictionary.h" namespace sdds{ template<typename T> class UniqueQueue : public Queue<T, 100>{ public: bool push(const T& item){ bool found = false; for(unsigned int i = 0; i < this->size() && !found; i++){ if((*this)[i] == item){ found = true; } } //deallocate memory if(!found){ return Queue<T, 100>::push(item); } return false; } }; template<> class UniqueQueue<double> : public Queue<double, 100>{ public: bool push(const double& item){ bool found = false; for(unsigned int i = 0; i < this->size() && !found; i++){ if(std::fabs((*this)[i] - item) <= 0.005){ found = true; } } if(!found){ return Queue<double, 100>::push(item); } return false; } //delete all memeory allocated by the UniqueQueu }; } #endif
Valgrind内存泄漏报告
HEAP SUMMARY: ==148192== in use at exit: 141 bytes in 4 blocks ==148192== total heap usage: 108 allocs, 104 frees, 80,216 bytes allocated ==148192== ==148192== 8 bytes in 1 blocks are definitely lost in loss record 1 of 4 ==148192== at 0x4C2A593: operator new(unsigned long) (vg_replace_malloc.c:344) ==148192== by 0x404322: sdds::Queue<long, 100u>::push(long const&) (Queue.h:47) ==148192== by 0x40544D: sdds::UniqueQueue<long>::push(long const&) (UniqueQueue.h:39) ==148192== by 0x40248C: main (w3_p2_prof.cpp:65) ==148192== ==148192== 8 bytes in 1 blocks are definitely lost in loss record 2 of 4 ==148192== at 0x4C2A593: operator new(unsigned long) (vg_replace_malloc.c:344) ==148192== by 0x403FDC: sdds::Queue<double, 100u>::push(double const&) (Queue.h:47) ==148192== by 0x403DA0: sdds::UniqueQueue<double>::push(double const&) (UniqueQueue.h:56) ==148192== by 0x4028BB: main (w3_p2_prof.cpp:110) ==148192== ==148192== 61 bytes in 1 blocks are indirectly lost in loss record 3 of 4 ==148192== at 0x4C2A593: operator new(unsigned long) (vg_replace_malloc.c:344) ==148192== by 0x4F6BD1E: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) (basic_string.tcc:219) ==148192== by 0x404A18: sdds::Dictionary::Dictionary(sdds::Dictionary const&) (Dictionary.h:29) ==148192== by 0x404D6D: sdds::Queue<sdds::Dictionary, 100u>::push(sdds::Dictionary const&) (Queue.h:47) ==148192== by 0x40536B: sdds::UniqueQueue<sdds::Dictionary>::push(sdds::Dictionary const&) (UniqueQueue.h:39) ==148192== by 0x402FCC: main (w3_p2_prof.cpp:159) ==148192== ==148192== 125 (64 direct, 61 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4 ==148192== at 0x4C2A593: operator new(unsigned long) (vg_replace_malloc.c:344) ==148192== by 0x404D5B: sdds::Queue<sdds::Dictionary, 100u>::push(sdds::Dictionary const&) (Queue.h:47) ==148192== by 0x40536B: sdds::UniqueQueue<sdds::Dictionary>::push(sdds::Dictionary const&) (UniqueQueue.h:39) ==148192== by 0x402FCC: main (w3_p2_prof.cpp:159) ==148192== ==148192== LEAK SUMMARY: ==148192== definitely lost: 80 bytes in 3 blocks ==148192== indirectly lost: 61 bytes in 1 blocks ==148192== possibly lost: 0 bytes in 0 blocks ==148192== still reachable: 0 bytes in 0 blocks ==148192== suppressed: 0 bytes in 0 blocks
问题排查与解决方案
泄漏原因分析
从Valgrind报告可以看出,所有泄漏的内存都来自Queue类的push方法中new创建的对象,根源在于**pop方法没有释放被弹出元素的堆内存**:
Queue::pop仅复制了数组第一个元素的值到临时变量,然后将后续元素前移,但没有delete原本的第一个元素指针,导致这块内存无法被回收,造成泄漏。- 不管是直接使用
Queue还是继承它的UniqueQueue,只要调用pop操作,都会触发这个问题。
修复方案
修改Queue.h中的pop方法,在移动数组元素前释放被弹出的元素内存:
T pop(){ T temp = *m_array[0]; delete m_array[0]; // 新增:释放被弹出元素的堆内存 for(unsigned int i = 0; i < m_size - 1; i++){ m_array[i] = m_array[i + 1]; } m_size--; return temp; }
额外验证
当前Queue的析构函数已经正确遍历数组并delete所有剩余元素,这部分逻辑无需修改。修复pop方法后,所有通过push分配的内存都会被正确释放,无论是在pop时还是对象销毁时。
重新编译程序并运行Valgrind检测,即可消除所有内存泄漏问题。
内容的提问来源于stack exchange,提问作者Kathe Caler
相关产品推荐
相关产品推荐

