对 struct c++ 使用 new 时出现 Bad_alloc 异常

发布于 2024-08-27 11:15:03 字数 1802 浏览 3 评论 0原文

我正在编写一个查询处理器,它分配大量内存并尝试查找匹配的文档。每当我找到匹配项时,我都会创建一个结构来保存描述文档的两个变量并将其添加到优先级队列中。由于无法知道我会执行此操作多少次,因此我尝试使用 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。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

清欢 2024-09-03 11:15:03

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

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

首先在堆上创建一个 DOC,然后在队列中存储该对象的副本,随后泄漏动态创建的 DOC< /代码>。

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

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

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));
深爱成瘾 2024-09-03 11:15:03

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

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

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.

明媚如初 2024-09-03 11:15:03

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

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

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

正如其他人提到的,如果您声明您的队列保存 Doc's 而不是 Doc*'s,那么您不必自己管理内存,容器会为您做这件事。

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.

呆橘 2024-09-03 11:15:03

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

而不是

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

执行“

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

或”操作

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

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文