【问题标题】:vector bad allocation error c++矢量错误分配错误 C++
【发布时间】:2014-05-19 08:13:16
【问题描述】:

我一直在研究一个基于向量的 avl 树。我想从文件中获取输入,但是在第 4118 个输入上它给了我一个 bad_alloc 错误。我做了一些研究并收集了我必须保留空间的输入。但即使我确实分配了空间,它仍然会给出同样的错误。

我的部分代码:

我调用这个函数:

void insert(T d, unsigned int c = 1);

find(T d) 在vector<node<T>*> myVector中找到newNode的位置; 即使没有找到newNode,它也会返回一个位置。 Insert 会处理返回的整数(如下所示)

插入是:

template<typename T>
void binaryTree<T>::insert(T d, unsigned int c)
//inserts type T with count c into vector
{
    node<T>* newNode = new node<T>(d,c);

    if(myVector.empty())
    {
        myVector.push_back(newNode);
    }
    else
    {
        int r = find(d);
        total++;
        //if newNode has same data as the data in position r
        if(r < myVector.size() && myVector[r] && *newNode == *myVector[r])
        {
            myVector[r]->data.loc.push_back(newNode->data.loc[0]);
            myVector[r]->count += newNode->count;
            delete newNode;
            return;
        }
        //insert into vector normally
        else
        {
            checkSpace(r);
            myVector[r] = newNode;
            //reParent(r);
        }
    }
}

checkSpace 为:

template<typename T>
void binaryTree<T>::checkSpace(int i)
//resizes the vector if needed
{
    if(i >= myVector.size())
    {
        myVector.resize(rightOi(i),NULL);
    }
}

并且 void reParent(r) 是执行所有旋转和平衡的主要功能。 我注释掉了 reParent(r),并且可能已经将问题隔离在插入函数中。我对此很陌生,我很感激任何帮助。提前谢谢你。

rightOi 函数:

template<typename T>
//return the right position of i
int binaryTree<T>::rightOi(int i)
{
    return i*2 + 2;
}

【问题讨论】:

  • 这看起来非常低效。不要在向量上调用resize。使用push_backinsert
  • 你能展示一下你的rightOi函数吗?
  • ^完成。它基本上返回某个位置的右孩子的位置。
  • 除非你在一些非常有限的平台上,否则你应该耗尽内存是很奇怪的。您是否有可能陷入无限递归,最终导致内存不足?
  • 所以你正在传递newNode。当它已经在树中时会发生什么?您对取消引用的节点和开槽节点进行值比较,并简单地增加树节点的计数。 调用者怎么知道你没有没有插入newNode,因此他们需要删除它?你返回void,所以我看不到调用者被通知newNode 的迹象仍然很热,并且不属于树。

标签: c++ stdvector bad-alloc


【解决方案1】:

所以我发现了问题,那就是 checkspace() 函数(它调整向量的大小)使向量调整为一个巨大的数字。这就是程序不断给我错误的原因。解决方法是仅在必要时调整大小。这就是我修复项目的方式。

【讨论】:

    【解决方案2】:

    我可能是错的,而且有点离题,但在我看来,该向量对于动态树来说不是一个好主意,我会创建树的老式方式,如下所示:

    struct Node
    {
        T value;
        Node* right;
        Node* left;
    }
    
    int main()
    {
        Node<int>* root = new Node<int>();
        root->value = 10;
        root->right = NULL;
        root->left = NULL;
    
        Node<int>* someNode = new Node<int>();
        someNode->value = 5;
        someNode->right = NULL;
        someNode->left = NULL;
    
        root->left = someNode;
    }
    

    因此,它可以按照您的规则包装到 AddElement、Rebalance、Traverse、Delete 等函数中。询问您是否需要更详细的说明。

    【讨论】:

    • 我宁愿用linkedlist创建一个二叉树,但是vector是必需的。
    猜你喜欢
    • 1970-01-01
    • 2016-11-07
    • 2014-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多