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;i cout您的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_ */