我编码的一个简单函数出现分段错误

Segmentation fault error occurs for a simple function I have coded

本文关键字:函数 简单 错误 分段 一个 编码      更新时间:2023-10-16

这里我只想定义一个函数,它返回矩阵的乘积,如果N是任意的,我想用new命令生成一个矩阵。当我执行功能时,我得到错误:

Segmentation fault (core dumped)

每当我为C赋值时,我都会出现这个错误,有人能告诉我发生了什么以及如何修复吗?

int **multiply(int **A, int **B, int N){
    int **C = new int*[N];
    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            for (int k = 0; k < N; k++)
                C[i][j] = C[i][j] + A[i][k] * B[k][j];
        }
    }
    return (C);
}

将矩阵作为指针的指针不是一个好主意。要做到这一点,你需要一个相当复杂的:

int **C = new int*[N];
for(int i = 0; i < N; ++ i)
    C[i] = new int[M];

释放这一点也是一个同样复杂的过程。还要想一想,如果其中一个operator new失败,并且您想要释放部分分配的矩阵,会发生什么。

将2D阵列存储在1D阵列中是一种惯例。你可以做:

int *C = new int[M * N];

然后元素被访问为:

C_ij = C[i + N * j];

或作为:

C_ij = C[j + M * i];

其中i[0, N)区间,j[0 to M)区间。这些实际上与编译器生成对恒定大小的2D数组的访问的方式非常相似(因此乘法实际上并不太昂贵,而且在考虑缓存时,整个过程可能比数组的数组快得多(。上面两行的区别在于,一行是列主行(当展开到1D时,列的元素是连续的项目(或交替的行主行。这是惯例问题。默认的"C"数组将是行主数组。一些库,如OpenGL或Eigen,使用列专业。

int **C=new int*[N];

这为指针数组腾出了空间。它不会初始化它们,所以它们可以指向任何地方。它们甚至可能是NULL指针。

C[i][j]

这可能会导致空指针取消引用。这可能就是造成分割错误的原因。

正如guest所指出的,C中的指针还没有初始化。您需要在第一个循环中初始化它们(注释1(,并在第二个循环中将它们的元素初始化为零(注释2(:
int **multiply(int **A, int **B, int N){
    int **C = new int*[N];
    for (int i = 0; i < N; i++) {
        C[i] = new int[N]; //1
        for (int j = 0; j < N; j++) {
            C[i][j] = 0; //2
            for (int k = 0; k < N; k++)
                C[i][j] = C[i][j] + A[i][k] * B[k][j];
        }
    }
    return (C);
}