1

我正在编写一个查询处理器,它分配大量内存并尝试查找匹配的文档。每当我找到匹配项时,我都会创建一个结构来保存描述文档的两个变量并将其添加到优先级队列中。由于无法知道我会这样做多少次,我尝试使用 new 动态创建我的结构。当我从优先级队列中弹出一个结构时,队列(STL 优先级队列实现)应该调用对象的析构函数。我的结构代码没有析构函数,所以我假设在这种情况下会调用默认析构函数。

但是,我第一次尝试创建 DOC 结构时,出现以下错误:

QueryProcessor.exe 中 0x7c812afb 处的未处理异常:Microsoft C++ 异常:内存位置 0x0012f5dc 处的 std::bad_alloc..

我不明白发生了什么 - 我是否用尽了太多内存以至于堆已满?似乎不太可能。而且好像我以前什至没有使用过那个指针。

所以:首先,我在做什么导致错误,其次,以下代码会多次工作吗?我是否需要为每个创建的结构创建一个单独的指针,或者我可以重复使用相同的临时指针并假设队列将保留一个指向每个结构的指针?

这是我的代码:

struct DOC{
    int docid;
    double rank;

    public:
        DOC()
        {
            docid = 0;
            rank = 0.0;
        }

        DOC(int num, double ranking)
        {
            docid = num;
            rank = ranking;

        }

        bool operator>( const DOC & d ) const {
           return rank > d.rank;
        }

        bool operator<( const DOC & d ) const {
           return rank < d.rank;
        }
};


//a lot of processing goes on here

        priority_queue<DOC, std::vector<DOC>, std::greater<DOC>> q;

//when a matching document is found, I do this:

rank = calculateRanking(table, num);

    //if the heap is not full, create a DOC struct with the docid and rank and add it to the heap
    if(q.size() < 20)
    {
        doc = new DOC(num, rank);
        q.push(*doc);
        doc = NULL;
    }

    //if the heap is full, but the new rank is greater than the 
    //smallest element in the min heap, remove the current smallest element
    //and add the new one to the heap
    else if(rank > q.top().rank)
    {
        q.pop();

        cout << "pushing doc on to queue" << endl;
        doc = new DOC(num, rank);
        q.push(*doc);
    }

非常感谢,bsg。

4

4 回答 4

4

为什么要在堆上创建以下结构:

doc = new DOC(num, rank);
q.push(*doc);

这首先在堆上创建 a DOC,然后将对象的副本存储在队列中,随后泄漏动态创建的DOC.

以下内容就足够了并且不会泄漏:

q.push(DOC(num, rank));
于 2010-04-04T17:50:47.063 回答
0

你有内存泄漏。STL 容器的插入方法存储您传入的类型的副本,因此您不需要在堆上分配 doc。

代替

doc = new DOC(...)
q.push(*doc);
doc = NULL;

做任何一个

doc(...);
q.push(doc);

或者

doc = new DOC(...);
q.push(*doc);
delete doc;
doc = NULL;
于 2010-04-04T17:46:33.113 回答
0

关于异常:该类bad_alloc有一个成员函数what(),它返回一个const char *包含错误原因的可读描述的字符串。

编辑:如果您正在考虑存储动态分配的对象,请存储指针而不是对该对象的引用。

于 2010-04-04T17:45:10.557 回答
0

内存不足时会抛出 std::bad_alloc 。

执行 q.pop() 时需要释放即将弹出的指针,否则会泄漏。如果你有很多元素,这可能是你的问题。

Doc *p = q.front();
delete p;
q.pop();

正如其他人所提到的,如果您声明队列来保存 Doc 而不是 Doc*,那么您不必自己管理内存,容器会为您完成。

于 2010-04-04T17:40:21.157 回答