全部错误校验和错误

时间:2015-02-12 05:45:56

标签: c++ memory malloc

我编写了一个程序,它深度优先搜索两个图形实现,一个邻接列表和一个邻接矩阵。但是,我的程序始终与以下行崩溃:

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;
}

编辑:想出来,愚蠢的错误,我分配的方式比向量所需的空间少,但程序很高兴在崩溃之前读取数百个值。

1 个答案:

答案 0 :(得分:0)

  

如果我自己没有分配任何内存,会导致此错误的原因是什么?

std::vector等人代表您分配内存。如果您误用它们,您可以轻松地获得与您遇到的类似的错误。

如果我不得不猜测,我会说你的代码中某处有一个越界访问权限(请记住std::vector []之类的运算符不会验证您正试图访问的索引。)

如果通过检查代码找不到错误,那么可能值得Valgrind去。