C++ std::调整大小时出现矢量和内存错误
我的结构定义如下:C++ std::调整大小时出现矢量和内存错误,c++,stdvector,C++,Stdvector,我的结构定义如下: struct Edge { int u, v; // vertices Edge() { } Edge(int u, int v) { this->u = u; this->v = v; } }; 还有一个类字段,定义如下 vector<Edge> solution; 当最后一次执行push_back时,我在Visual Studio的调试模式下得到一个错误窗口 [App
struct Edge
{
int u, v; // vertices
Edge() { }
Edge(int u, int v)
{
this->u = u;
this->v = v;
}
};
还有一个类字段,定义如下
vector<Edge> solution;
当最后一次执行push_back
时,我在Visual Studio的调试模式下得到一个错误窗口
[AppName]已触发断点
调试器转到malloc.c
,到\u heap\u alloc
函数的末尾。在第7行之前,向量似乎工作正常。我可以看到调试器中的所有元素。向量似乎在重新分配自身(扩展其大小)时遇到了问题
有趣的是,如果我把这个放在所有的推回之前:
solution.reserve(7);
,正确添加第7条边。更有趣的是,试图为超过22个元素保留空间也会导致上述错误
我做错了什么?如何调试它?应用程序的其余部分没有占用这么多内存,所以我不敢相信堆已经满了
更多的代码,根据要求。这是度量旅行商问题的2-近似算法的一个相当草率的实现。它首先创建一个最小生成树,然后按DFS顺序将顶点(仅索引)添加到
partialSolution
向量
void ApproxTSPSolver::Solve()
{
// creating a incidence matrix
SquareMatrix<float> graph(noOfPoints);
for (int r=0; r<noOfPoints; r++)
{
for (int c=0; c<noOfPoints; c++)
{
if (r == c)
graph.SetValue(r, c, MAX);
else
graph.SetValue(r, c, points[r].distance(points[c]));
}
}
// finding a minimum spanning tree
spanningTree = SquareMatrix<bool>(noOfPoints);
// zeroeing the matrix
for (int r=0; r<noOfPoints; r++)
for (int c=0; c<noOfPoints; c++)
spanningTree.SetValue(r, c, false);
bool* selected = new bool[noOfPoints];
memset(selected, 0, noOfPoints*sizeof(bool));
selected[0] = true; // the first point is initially selected
float min;
int minR, minC;
for (int i=0; i<noOfPoints - 1; i++)
{
min = MAX;
for (int r=0; r<noOfPoints; r++)
{
if (selected[r] == false)
continue;
for (int c=0; c<noOfPoints; c++)
{
if (selected[c] == false && graph.GetValue(r, c) < min)
{
min = graph.GetValue(r, c);
minR = r;
minC = c;
}
}
}
selected[minC] = true;
spanningTree.SetValue(minR, minC, true);
}
delete[] selected;
// traversing the tree
DFS(0);
minSol = 0.0f;
// rewriting the solution to the solver's solution field
for (int i=0; i<noOfPoints - 1; i++)
{
solution.push_back(Edge(partialSolution[i], partialSolution[i + 1]));
minSol += points[partialSolution[i]].distance(points[partialSolution[i + 1]]);
}
solution.push_back(Edge(partialSolution[noOfPoints - 1], partialSolution[0]));
minSol += points[partialSolution[noOfPoints - 1]].distance(points[partialSolution[0]]);
cout << endl << minSol << endl;
solved = true;
}
void ApproxTSPSolver::DFS(int vertex)
{
bool isPresent = std::find(partialSolution.begin(), partialSolution.end(), vertex)
!= partialSolution.end();
if (isPresent == false)
partialSolution.push_back(vertex); // if I comment out this line, the error doesn't occur
for (int i=0; i<spanningTree.GetSize(); i++)
{
if (spanningTree.GetValue(vertex, i) == true)
DFS(i);
}
}
class ApproxTSPSolver : public TSPSolver
{
vector<int> partialSolution;
SquareMatrix<bool> spanningTree;
void DFS(int vertex);
public:
void Solve() override;
};
TSPSolver.c的一部分:
TSPSolver::TSPSolver()
{
points = NULL;
solved = false;
}
TSPSolver::~TSPSolver()
{
if (points)
delete[] points;
}
void TSPSolver::LoadFromFile(string path)
{
ifstream input(path);
string line;
int nodeID;
float coordX, coordY;
bool coords = false;
minX = numeric_limits<float>::max();
maxX = numeric_limits<float>::min();
minY = numeric_limits<float>::max();
maxY = numeric_limits<float>::min();
while (input.good())
{
if (coords == false)
{
getline(input, line);
if (line == "NODE_COORD_SECTION")
{
coords = true;
}
else if (line.find("DIMENSION") != string::npos)
{
int colonPos = line.find_last_of(":");
noOfPoints = stoi(line.substr(colonPos + 1));
#ifdef _DEBUG
cout << noOfPoints << " points" << endl;
#endif
// allocating memory for this amount of points
points = new Point[noOfPoints];
}
}
else
{
input >> nodeID >> coordX >> coordY;
points[nodeID - 1].X = coordX;
points[nodeID - 1].Y = coordY;
minX = min(minX, coordX);
maxX = max(maxX, coordX);
minY = min(minY, coordY);
maxY = max(maxY, coordY);
if (nodeID == noOfPoints)
{
break;
}
}
}
input.close();
}
TSPSolver::TSPSolver()
{
点数=零;
已解决=错误;
}
TSPSolver::~TSPSolver()
{
如果(点数)
删除[]点;
}
void TSPSolver::LoadFromFile(字符串路径)
{
ifstream输入(路径);
弦线;
int-nodeID;
浮动coordX,coordY;
布尔坐标=假;
minX=数值限制::max();
maxX=数值限制::min();
minY=数值限制::max();
maxY=数值限制::min();
while(input.good())
{
if(coords==false)
{
getline(输入,行);
如果(行==“节点协调部分”)
{
coords=true;
}
else if(line.find(“维度”)!=string::npos)
{
int colonPos=line.find最后一行(“:”);
noOfPoints=stoi(line.substr(colonPos+1));
#ifdef_调试
cout>coordX>>coordY;
点[nodeID-1].X=coordX;
点[nodeID-1].Y=coordY;
minX=min(minX,coordX);
maxX=max(maxX,coordX);
minY=min(minY,coordY);
maxY=max(maxY,coordY);
if(nodeID==noOfPoints)
{
打破
}
}
}
input.close();
}
这与其说是回答,不如说是评论,但篇幅太有限了
如果您在windows上,请尝试。它可能会检测到错误的内存访问
检测这种访问的另一种方法是重新保存初始化为0的空字符数组
打开声明向量的类,并声明一个字符数组,在向量前后各声明64个字符,并将它们初始化为0!。
然后进入向量代码,在那里生成错误,并检查那些填充数组的内容。如果它们被填充,则有人会写得更多
定位“恶意”访问的一种方法(至少在VC++中)是在填充数组中设置一个数据断点,然后检查调用堆栈。您可能在不同的位置对
点进行越界访问,例如,这个:
input >> nodeID >> coordX >> coordY;
points[nodeID - 1].X = coordX;
如果输入失败,或者值超出范围怎么办
我建议从代码中删除new
和delete
和[]
的所有用法;例如,假设点
是int*点;
然后用std::vector points
替换。将所有[]
访问更改为.at()
并捕获异常。对所有没有正确复制语义的类禁用复制
然后,您可以更确定这不是内存分配错误、复制错误或越界访问(这是解释您症状的有力候选)
这还可以解决TSPSolver
当前没有正确的复制语义的问题
做一个SSCCE是非常有用的。你提到有“很多输入”,尝试尽可能减少输入,但仍然会出现问题。SSCCE可以包含输入数据,只要其大小可以管理,您可以发布。正如他们所说,当前您显示的代码太多,但还不够。问题仍然潜伏在您尚未发布的某个地方。您的代码看起来是正确的。也许您有错误这里是程序中的其他元素,例如写入无效的内存地址。矢量7元素在实际代码中的长度是数千还是数百万?@Cyber,在实际代码中,矢量最初是空的。因此,尝试将第7元素添加到矢量时会发生错误。@PiotrK:您可以尝试以下操作:请使用Edge(int-uu,int-vv):u(uu),v(vv){}
。它比您当前的构造函数更有效。感谢您的想法。“zero”方法没有返回任何有趣的结果,两个数组仍然充满了0。我无法设置“扫描”超过4个字节的数据断点,这使它们基本上没用。我收到以下错误:“无法设置断点。硬件不支持监视请求的字节数。”。我必须尝试你们建议的工具,也许其中一些工具会告诉我一些事情。
TSPSolver::TSPSolver()
{
points = NULL;
solved = false;
}
TSPSolver::~TSPSolver()
{
if (points)
delete[] points;
}
void TSPSolver::LoadFromFile(string path)
{
ifstream input(path);
string line;
int nodeID;
float coordX, coordY;
bool coords = false;
minX = numeric_limits<float>::max();
maxX = numeric_limits<float>::min();
minY = numeric_limits<float>::max();
maxY = numeric_limits<float>::min();
while (input.good())
{
if (coords == false)
{
getline(input, line);
if (line == "NODE_COORD_SECTION")
{
coords = true;
}
else if (line.find("DIMENSION") != string::npos)
{
int colonPos = line.find_last_of(":");
noOfPoints = stoi(line.substr(colonPos + 1));
#ifdef _DEBUG
cout << noOfPoints << " points" << endl;
#endif
// allocating memory for this amount of points
points = new Point[noOfPoints];
}
}
else
{
input >> nodeID >> coordX >> coordY;
points[nodeID - 1].X = coordX;
points[nodeID - 1].Y = coordY;
minX = min(minX, coordX);
maxX = max(maxX, coordX);
minY = min(minY, coordY);
maxY = max(maxY, coordY);
if (nodeID == noOfPoints)
{
break;
}
}
}
input.close();
}
input >> nodeID >> coordX >> coordY;
points[nodeID - 1].X = coordX;