Bad_alloc exception when using new for a struct c++

久未见 提交于 2019-12-11 07:26:02

问题


I am writing a query processor which allocates large amounts of memory and tries to find matching documents. Whenever I find a match, I create a structure to hold two variables describing the document and add it to a priority queue. Since there is no way of knowing how many times I will do this, I tried creating my structs dynamically using new. When I pop a struct off the priority queue, the queue (STL priority queue implementation) is supposed to call the object's destructor. My struct code has no destructor, so I assume a default destructor is called in that case.

However, the very first time that I try to create a DOC struct, I get the following error:

Unhandled exception at 0x7c812afb in QueryProcessor.exe: Microsoft C++ exception: std::bad_alloc at memory location 0x0012f5dc..

I don't understand what's happening - have I used up so much memory that the heap is full? It doesn't seem likely. And it's not as if I've even used that pointer before.

So: first of all, what am I doing that's causing the error, and secondly, will the following code work more than once? Do I need to have a separate pointer for each struct created, or can I re-use the same temporary pointer and assume that the queue will keep a pointer to each struct?

Here is my code:

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);
    }

Thank you very much, bsg.


回答1:


Why are you creating the structure in the following on the heap:

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

This first creates a DOC on the heap, then stores a copy of the object in the queue and subsequently leaks the dynamically created DOC.

The following would be sufficient and doesn't leak:

q.push(DOC(num, rank));



回答2:


About the exception: The class bad_alloc has a member function what() which returns a const char * to a string containing a readable description of the cause of the error.

EDIT: If you are considering storing a dynamically allocated object, store the pointer and not a reference to the object.




回答3:


std::bad_alloc is thrown when you are out of memory.

You need to free the pointer you are about to pop when you do the q.pop(), else you are leaking. If you have a LOT of elements this could be your problem.

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

As others have mentioned, if you declare your queue to hold Doc's instead of Doc*'s, then you don't have to manage memory yourself and the container will do it for you.




回答4:


You have a memory leak. The insertion methods for STL containers store a copy of the type you pass in so you don't need to allocate doc on the heap.

Instead of

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

Do either

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

Or

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


来源:https://stackoverflow.com/questions/2575275/bad-alloc-exception-when-using-new-for-a-struct-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!