You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 22:01:18