【问题标题】:Exception thrown at 0x7BC9E829 (ucrtbased.dll) in Project1CSCI115.exe: 0xC0000005: Access violation reading location 0x80A801E4 [duplicate]Project1CSCI115.exe 中的 0x7BC9E829 (ucrtbased.dll) 引发异常:0xC0000005:访问冲突读取位置 0x80A801E4 [重复]
【发布时间】:2021-07-31 09:45:44
【问题描述】:

我正在编写一些将邻接矩阵转换为邻接列表的代码,但遇到了问题。我将其追溯到内存错误,但是当我使用调试器单步执行时,它会直接跳过错误,并且不会引发异常。当程序在没有断点的情况下运行时,它会抛出异常。我有一种感觉是由于堆损坏,但我不是专家。

#include <string>
#include <limits>
#include <iostream>

using namespace std;

class NodeAM {
public:
    NodeAM() : v(0), weight(0), next(nullptr) {}
    NodeAM(int v1, double weight1) : v(v1), weight(weight1), next(nullptr) {}
    ~NodeAM() {}
    int v;
    double weight;
    NodeAM* next;
};

class matrix {
public:
    matrix();
    matrix(int m, int n);
    ~matrix();

    void setCurrentVertex(int u);
    void setAdjacencyMatrix(map* mapMatrix);
    void setDirectEdge(int u, int v, double w);

private:
    NodeAM** aMatrix;
    NodeAM** curr;
    int numVertices;
    int infinity = std::numeric_limits<int>::max(); //displayed as INF
};


matrix::matrix() {
    numVertices = 0;
}

matrix::matrix(int m, int n) {
    numVertices = m * n;
    aMatrix = new NodeAM * [n]; //n is columns
    curr = new NodeAM * [n];
    for (int i = 0; i < n; ++i) {
        aMatrix[i] = nullptr;
        curr[i] = nullptr;
    }
}

matrix::~matrix() {
    for (int i = 0; i < numVertices; ++i) {
        NodeAM* curr = aMatrix[i];
        while (curr) {
            NodeAM* next = curr->next;
            delete curr;
            curr = next;
        }
    }
    delete[] aMatrix;
    delete[] curr;
}

void matrix::setAdjacencyMatrix(map* mapMatrix) {
    double weightArr;

    for (int i = 0; i < numVertices; ++i) {
        for (int j = 0; j < numVertices; ++j) {
            if (mapMatrix->valueAt(i, j) != infinity) {
                weightArr = mapMatrix->valueAt(i, j);
                setDirectEdge(i, j, weightArr);
            }

        }
    }
}

void matrix::setDirectEdge(int u, int v, double w) {
    NodeAM* tmp = new NodeAM(v, w); //exception thrown when u is 22 and v is 23
    tmp->next = aMatrix[u];
    aMatrix[u] = tmp;
}

double map::valueAt(int row, int cols) {
    return adjMatrixCopy[row][cols];
}
/*
for the sake of not posting tons of code, adjMatrixCopy is an adjacency
matrix, which either has infinity as the edge or the edge weight (1, 4, 7, etc.) as
the edge, like this:

INF, INF, 7, 3, 7
INF, INF, 3, 7, 7
1, 9999, INF, 7, 3

In adjMatrixCopy, it is a 50 x 50 matrix similar to the one above
*/

【问题讨论】:

  • 仅仅因为你的程序在一个特定的地方崩溃并不意味着问题就出在那个地方。 C++ 不能以这种方式工作。问题可能出现在程序中执行到该点的任何地方,除了该错误没有导致立即崩溃,而是程序继续运行到该点,当它最终由于“堆损坏”而崩溃时。您需要显示一个minimal reproducible example,任何其他人都可以剪切/粘贴,完全如图所示,自己编译、运行和重现他们的崩溃;在那之前,任何人都不太可能知道崩溃的原因。
  • map 类型在哪里?
  • 您的matrix 析构函数看起来很奇怪,您在同一类型上使用delete[]delete
  • for (int i = 0; i &lt; numVertices; ++i) { NodeAM* curr = aMatrix[i]; 这看起来不对。 aMatrix 只有n 元素,没有n*m 元素
  • @IgorTandetnik 谢谢,这是罪魁祸首。在我的构造函数中查看之后,我意识到我在数组中放入的内存值超出了它的处理能力,因此程序在一个奇怪的地方崩溃了。

标签: c++ pointers matrix dijkstra


【解决方案1】:

构造函数应该是

matrix::matrix() {
    numVertices = 0;
}

matrix::matrix(int m, int n) {
    numVertices = m * n;
    aMatrix = new NodeAM * [n*m]; //n is columns
    curr = new NodeAM * [n];
    currVert = new int[n];
    for (int i = 0; i < n; ++i) {
        aMatrix[i] = nullptr;
        curr[i] = nullptr;
    }
}

在 aMatrix = new NodeAM* [n*m] 处,数组应该是邻接矩阵的大小,以防它必须存储矩阵的每个值。这就是它抛出异常的原因,因为它没有足够的内存来保存邻接矩阵的值。

【讨论】:

    猜你喜欢
    • 2021-02-14
    • 1970-01-01
    • 1970-01-01
    • 2016-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 1970-01-01
    相关资源
    最近更新 更多