我编写了一个程序,它深度优先搜索两个图形实现,一个邻接列表和一个邻接矩阵。但是,我的程序始终与以下行崩溃:
HPCHW2(1532,0x7fff727c6310)malloc:***对象0x1002000c8的错误:释放对象的校验和不正确 - 对象可能在被释放后被修改。
两个十六进制数字在不同的运行中是相同的。但是,此崩溃发生在不同运行的不同行上,并且我自己没有在此程序中分配任何堆内存。该程序总是使它超过main中的第一个外部for循环,但随后在第二次迭代中在AdjacencyMatrixGraph
代码中的某处崩溃。大多数崩溃都在方法connected
中,但是在不同的行和不同的变量中,有时在我推到stack
时崩溃,有时我在定义时崩溃变量discovered
。该程序在AdjacencyMatrixGraph
的构造函数中也崩溃了一次。
如果我自己没有分配任何内存,会导致此错误的原因是什么?我假设任何引擎盖分配通常都不应该修改释放的内存。另外,我将如何调试此错误?
这是C ++ 11,我在Mac OS Mavericks上。
这是我的参考代码:
AdjacencyList.cpp
#include "AdjacencyListGraph.h"
#include <cstdlib>
using std::list;
AdjacencyListGraph::AdjacencyListGraph(int size) :
adjacencyList(vector<vector<int>>(size)),
_size(size) {
}
void AdjacencyListGraph::addEdge(int begin, int end) {
adjacencyList[begin].push_back(end);
adjacencyList[end].push_back(begin);
}
int AdjacencyListGraph::size() {
return _size;
}
bool AdjacencyListGraph::connected(int begin, int end) {
// stack to track vertices to process
list<int> stack = list<int>();
stack.push_front(begin);
// value of discovered[i] is whether vertex i has been discovered
vector<bool> discovered = vector<bool>(size(), false);
while (!stack.empty()) {
// process top vertex
int curr = stack.front();
stack.pop_front();
if (!discovered[curr]) {
discovered[curr] = true;
vector<int>& neighbors = adjacencyList[curr];
// examine neighbors
for (size_t i = 0; i < neighbors.size(); ++i) {
int neighbor = neighbors[i];
// done
if (neighbor == end) {
return true;
}
// else process later
stack.push_front(neighbor);
}
}
}
return false;
}
AdjacencyMatrixGraph.cpp
#include "AdjacencyMatrixGraph.h"
using std::list;
AdjacencyMatrixGraph::AdjacencyMatrixGraph(int size) :
adjacencyMatrix(vector<bool>(size * size, false)),
_size(size) {
// has crashed here once
}
void AdjacencyMatrixGraph::addEdge(int begin, int end) {
if (begin == end) {
return;
}
adjacencyMatrix[begin * size() + end] = true;
adjacencyMatrix[end * size() + begin] = true;
}
int AdjacencyMatrixGraph::size() {
return _size;
}
bool AdjacencyMatrixGraph::connected(int begin, int end) {
// stack to track vertices to process
list<int> stack = list<int>();
stack.push_front(begin); // sometimes crashes here
// value of discovered[i] is whether vertex i has been discovered
vector<bool> discovered = vector<bool>(size(), false); // sometimes crashes here
while (!stack.empty()) {
// process top vertex
int curr = stack.front();
stack.pop_front();
if (!discovered[curr]) {
discovered[curr] = true;
// examine neighbors
for (int i = 0; i < size(); ++i) {
// no edge between curr and i
if (!adjacencyMatrix[curr * size() + i]) {
continue;
}
// done
if (i == end) {
return true;
}
// else process later
stack.push_front(i); // sometimes crashes here
}
}
}
return false;
}
的main.cpp
#include <cstdio>
#include <vector>
#include <set>
#include <chrono>
#include <random>
#include <algorithm>
#include "AdjacencyListGraph.h"
#include "AdjacencyMatrixGraph.h"
using std::vector;
using std::set;
using std::chrono::high_resolution_clock;
using std::chrono::duration;
using std::chrono::duration_cast;
using std::mt19937;
void clearCache() {
const vector<int> intsToSum = vector<int>(1e9, 1);
volatile long long sum = 0;
for (size_t i = 0; i < intsToSum.size(); ++i) {
sum += intsToSum[i];
}
}
bool randomBool() {
const double seed = high_resolution_clock::now().time_since_epoch().count();
mt19937 mt_rand(seed);
return bool(mt_rand() % 2);
}
vector<bool> randomAdjacencyMatrix(int size) {
vector<bool> adjacencyMatrix = vector<bool>(size);
for (int i = 0; i < size * size; ++i) {
adjacencyMatrix[i] = randomBool();
}
return adjacencyMatrix;
}
int main() {
const vector<int> sizes = {20, 50, 100, 200};
const int numRepeats = 1;
for (int i = 0; i < sizes.size(); ++i) {
int size = sizes[i];
printf("size: %d\n", size);
/* Initialize function-wide variables */
vector<bool> adjacencyMatrix = randomAdjacencyMatrix(size);
high_resolution_clock::time_point start;
high_resolution_clock::time_point stop;
/* Initialize adjacency matrix */
AdjacencyMatrixGraph adjacencyMatrixGraph = AdjacencyMatrixGraph(size);
for (int row = 0; row < size; ++row) {
for (int col = 0; col < size; ++col) {
if (adjacencyMatrix[row * size + col]) {
adjacencyMatrixGraph.addEdge(row, col);
}
}
}
/* Time 1 */
double time1Elapsed = 0;
volatile int count = 0;
for (int j = 0; j < numRepeats; ++j) {
clearCache();
start = high_resolution_clock::now();
for (int begin = 0; begin < size; ++begin) {
for (int end = 0; end < size; ++end) {
if (adjacencyMatrixGraph.connected(begin, end)) {
++count;
}
}
}
stop = high_resolution_clock::now();
time1Elapsed += duration_cast<duration<double>>(stop - start).count();
}
printf(" time1 -- average time: %f\n", time1Elapsed / numRepeats);
/* Initialize adjacency list */
AdjacencyListGraph adjacencyListGraph = AdjacencyListGraph(size);
for (int row = 0; row < size; ++row) {
for (int col = 0; col < size; ++col) {
if (adjacencyMatrix[row * size + col]) {
adjacencyListGraph.addEdge(row, col);
}
}
}
/* Time 2 */
double time2Elapsed = 0;
count = 0;
for (int j = 0; j < numRepeats; ++j) {
clearCache();
start = high_resolution_clock::now();
for (int begin = 0; begin < size; ++begin) {
for (int end = 0; end < size; ++end) {
if (adjacencyListGraph.connected(begin, end)) {
++count;
}
}
}
stop = high_resolution_clock::now();
time2Elapsed += duration_cast<duration<double>>(stop - start).count();
}
printf(" time2 -- average time: %f\n\n", time2Elapsed / numRepeats);
}
return 0;
}
编辑:想出来,愚蠢的错误,我分配的方式比向量所需的空间少,但程序很高兴在崩溃之前读取数百个值。
答案 0 :(得分:0)
如果我自己没有分配任何内存,会导致此错误的原因是什么?
std::vector
等人代表您分配内存。如果您误用它们,您可以轻松地获得与您遇到的类似的错误。
如果我不得不猜测,我会说你的代码中某处有一个越界访问权限(请记住std::vector
[]
之类的运算符不会验证您正试图访问的索引。)
如果通过检查代码找不到错误,那么可能值得Valgrind去。