队列中不寻常的内存泄漏 - 代码在退出时挂起

时间:2013-09-13 10:51:01

标签: c++ memory-leaks queue

我需要创建一个类的队列,然后由一个线程处理。问题是每次我添加对象的引用时,队列都会为该类分配内存,从而导致巨大的内存泄漏。这也导致程序在退出时挂起。

将TaskClass对象的12345678引用添加到TaskQueue会导致137MB内存泄漏。 请注意,调用queue.pop()时不会释放内存。

类TaskQueue:

template <class tjob>
class TaskQueue
{
private:
    std::queue<tjob> _taskqueue;
public:
    TaskQueue()
    {
        //constructor goes here
    }
    //add task to queue
    template < typename Class>
    bool AddTask( Class &PClass)
    {
        _taskqueue.push(PClass);
        return true;
    }
    bool ProcessQueue()
    {
        while (!_taskqueue.empty())
        {
            _taskqueue.front().run();
            _taskqueue.pop();
        }
        return true;
    }
    //run a function pointer
    template < typename Task >
    bool RunTask( Task task){
        task();
        return true;
    }
    //call class entry point member .run
    template < typename Class>
    bool RunClass ( Class& PClass){
        PClass.run();
        return true;
    }
    //return remaining tasks
    int GetRemainingTasks(){
        return _taskqueue.size();
    }
};

class TaskClass:

class TaskClass 
{
protected:
    int *ptr_x;
public:
    TaskClass() {
        std::cout << "TaskClass Constructor called\n";
        ptr_x = new int(0);
    }
    bool run(){
        *ptr_x = *ptr_x + 1;
        return true;
    }
    bool printx(){
        std::cout << "x is now " << *ptr_x << std::endl;
        return true;
    }
    ~TaskClass(){
        //std::cout << "TaskClass destructor called!\n";
    }
};

主:

int main()
{
    TaskClass job1;
    int nojobs = 12345678;
    TaskQueue<TaskClass> TestQueue;
    std::cout << "Preparing Queue... Adding " << nojobs << " tasks.. "; //std::cin.get();
    for (int i=0;i<nojobs;i++)
        TestQueue.AddTask(job1);
    std::cout << "Done!\n"; //std::cin.get();
    std::cout << "Processing Queue... "; 
    TestQueue.ProcessQueue();
    std::cout << "Done!\n"; 
    job1.printx();
    std::cout << "Remaining tasks: " << TestQueue.GetRemainingTasks() << std::endl;
    //std::cin.get(); 
    //exit(0);
    return 0;
}

1 个答案:

答案 0 :(得分:1)

内存泄漏

ptr_x = new int(0);

因为从不删除该内存。至少,您需要在析构函数中删除它,并添加一个深层复制它的复制构造函数。 更好的解决方案是用简单的

替换指针
class TaskClass 
{
protected:
    int x;

(虽然我不明白为什么它会像在billz的答案中那样static。)


偶然的不正当行为:

  1. 不必要的模板:

    template < typename Class>
    bool AddTask( Class &PClass) {
    

    Class唯一有效的类型是类模板参数tjob,那么为什么要模拟这个方法呢?为什么需要非const参考只能复制的东西?

    bool AddTask(tjob const &job) {
        _taskqueue.push(job);
        return true;
    }
    

    更好。与其他模板化方法类似。

  2. 我需要创建类的队列

    不,你没有,事实上你不能(我想如果你真的想要的话,你可以创建typeinfo_t的队列)。您需要创建对象的队列。幸运的是,这是你实际在做的事情,因为调用对象引用PClass并不能使它成为指向类的指针。

    这似乎(实际上)是迂腐的,但如果你的术语正确,那么每个人通常都会更容易。