C++ 性能崩溃C++;(标准向量错误分配)

C++ 性能崩溃C++;(标准向量错误分配),c++,performance,vector,graph,nodes,C++,Performance,Vector,Graph,Nodes,下面的代码是关于实时搜索邻居的。一旦一个新节点添加到我的图形中,就会调用该节点的函数updateseqneights。我所知道的是,新节点肯定是上一个添加的节点的邻居。在下一步中,我使用这一事实查看先前添加的节点的邻域,找到最接近新节点的节点,然后在该邻域中搜索最近的邻居 例如,我只重复了3次,将一个节点的邻居数限制为4,以保持计算的时间框架不变。它工作得很好,除了在大约30个节点之后,计算时间增加得非常快,每增加一个节点都会导致错误分配异常 #ifndef GRAPH_NODE_H_ #def

下面的代码是关于实时搜索邻居的。一旦一个新节点添加到我的图形中,就会调用该节点的函数
updateseqneights
。我所知道的是,新节点肯定是上一个添加的节点的邻居。在下一步中,我使用这一事实查看先前添加的节点的邻域,找到最接近新节点的节点,然后在该邻域中搜索最近的邻居

例如,我只重复了3次,将一个节点的邻居数限制为4,以保持计算的时间框架不变。它工作得很好,除了在大约30个节点之后,计算时间增加得非常快,每增加一个节点都会导致
错误分配
异常

#ifndef GRAPH_NODE_H_
#define GRAPH_NODE_H_

#include <vector>
#include <cmath>

#include <iostream>

using namespace std;

class Node {
public:
    double x;
    double y;

    Node* nodePrev;

    vector<Node> seqNeighbours;

    //Constructor
    Node();
    Node(double x, double y);
    virtual ~Node();

    //Operator functions
    Node& operator=(const Node& n);

    //Get&Set
    int getID();

    //Public member functions
    void addNeighbour(Node& n);

    bool isSeqNeighbour(int ID);

    int updateSeqNeighbours();

    double distanceTo(Node& n);

private:
    static int count;
    int ID;

    void _setDefaults();
};

int Node::count = 0;

Node::Node() {
    _setDefaults();
}

Node::Node(double x, double y) {
    _setDefaults();
    this->x = x;
    this->y = y;
}

Node::~Node() {
    // TODO Auto-generated destructor stub
}

//Operator functions
Node& Node::operator=(const Node& n) {
    if (this != &n) {
        ID = n.ID;
            x = n.x;
            y = n.y;
        seqNeighbours.clear();
        seqNeighbours = n.seqNeighbours;
        nodePrev = n.nodePrev;
    }
    return *this;
}

//Get&Set
int Node::getID() {
    return this->ID;
}

//Public member functions
void Node::addNeighbour(Node& n) {
    seqNeighbours.push_back(n);
}

double Node::distanceTo(Node& n) {
    return sqrt((n.x-x)*(n.x-x) + (n.y-y)*(n.y-y));
}

bool Node::isSeqNeighbour(int ID) {
    for (int i = 0; i < seqNeighbours.size(); i++) {
        if (seqNeighbours[i].getID() == ID) {
            return true;
        }
    }
    return false;
}

int Node::updateSeqNeighbours() {
    if (nodePrev == NULL) {
        return 1;
    } else {
        Node seed = *nodePrev;  //previous node as seed
        seqNeighbours.push_back(seed);

            for (int i = 0; i < 3; i++) {
                    if (seed.nodePrev == NULL) break;
                    double minDist = 15353453;
                    Node closest;
                    for (int j = 0; j < seed.seqNeighbours.size(); j++) {
                            double dist = distanceTo(seed.seqNeighbours[j]);
                            if (dist < minDist) {
                                    minDist = dist;
                                    closest = seed.seqNeighbours[j];
                            }
                    }
                    if (minDist < 150) {
                            seqNeighbours.push_back(closest);
                    }
                    seed = closest;
            }
            cout << "neighbours = " << seqNeighbours.size() << endl;
    }
    return 0;
}

void Node::_setDefaults() {
    x = 0;
    y = 0;
    ID = count;
    nodePrev = NULL;
    seqNeighbours.clear();
    count++;
}
#endif /* GRAPH_NODE_H_ */
\ifndef图\u节点\u H_
#定义图节点_
#包括
#包括
#包括
使用名称空间std;
类节点{
公众:
双x;
双y;
Node*nodePrev;
矢量序列邻居;
//建造师
Node();
节点(双x,双y);
虚拟节点();
//算子函数
节点和运算符=(常量节点和n);
//获取并设置
int getID();
//公职人员职能
无效添加邻居(节点&n);
bool-isseqnexter(int-ID);
int updateseqneights();
双距离到(节点&n);
私人:
静态整数计数;
int-ID;
void_setDefaults();
};
int Node::count=0;
Node::Node(){
_setDefaults();
}
节点::节点(双x,双y){
_setDefaults();
这个->x=x;
这->y=y;
}
节点::~Node(){
//TODO自动生成的析构函数存根
}
//算子函数
节点和节点::运算符=(常量节点和n){
如果(此!=&n){
ID=n.ID;
x=n.x;
y=n.y;
seq.clear();
seqneights=n.seqneights;
nodePrev=n.nodePrev;
}
归还*这个;
}
//获取并设置
int节点::getID(){
返回此->ID;
}
//公职人员职能
无效节点::添加邻居(节点(&n){
1.推回(n);
}
双节点::距离到(节点(&n){
返回sqrt((n.x-x)*(n.x-x)+(n.y-y)*(n.y-y));
}
bool节点::isseqnexter(int-ID){
对于(int i=0;icout您的
seqneights
向量
。这意味着它存储邻居本身,而不是指向它们或它们的索引的指针。因此,复制构造函数复制所有邻居。复制每个邻居反过来需要复制其邻居,这需要复制其邻居,依此类推。您的赋值lso复制所有邻居,这需要复制它们的邻居,依此类推。这意味着每个副本都会以指数方式增加内存负载,直到系统无法存储所有邻居、邻居等


附言:一个叫做“列表”的向量是个坏主意。它就像一个叫做“向量”的列表,一个叫做“地图”的集合,或者是一只叫做Dog的猫。

节点类的复制构造函数在哪里?你能把崩溃跟踪也放进去吗?对nodePrev使用指针看起来不太正确。你能把实际使用这个类的代码放进去吗?为什么你不能用调试器呢?@Arunmu:1)还没有实现一个,我当前的代码中需要它吗?2)C鲁莽的消息被更新了,希望这就是你的意思?!3)完成了。@Ajay:使用在borland 6中运行的大学软件,但真的不知道如何调试它:D@laxn_pander是的,为了确保代码的正确性,您需要一个复制构造函数。对于NodePrev,您不需要进行深度复制,只需分配指针即可。非常感谢。使total sense.你在列表上的注释是有效的,你可能会猜到我是工程师而不是程序员:你要么将其设置为
vector
,而不是
vector
,要么将此字段从节点中删除,并将邻接矩阵存储在
Graph
类中。例如,邻接矩阵可以存储为
vectoradj;
,这意味着
adj[i][j]
adj[i]
的第j个邻居的索引。
#ifndef GRAPH_GRAPH_H_
#define GRAPH_GRAPH_H_

#include <vector>
#include <iostream>
#include "Node.h"

using namespace std;

class Graph {
public:
    Graph();
    virtual ~Graph();

    vector<Node> list;

    void addNode(Node& n);
    void addSeqNode(Node& n);


private:
    void _setDefaults();
};

Graph::Graph() {
    // TODO Auto-generated constructor stub

}

Graph::~Graph() {
    // TODO Auto-generated destructor stub
}

void Graph::addNode(Node& n) {
    list.push_back(n);
}

void Graph::addSeqNode(Node& n) {
    if (!list.empty()) {
        n.nodePrev = &list.back();
    }
    n.updateSeqNeighbours();
    list.push_back(n);
}

void Graph::_setDefaults() {
    list.clear();
}


#endif /* GRAPH_GRAPH_H_ */