打印多维数组的内容时出现分段错误

Segmentation fault when printing contents of a multidimensional array

我是 运行 下面的 C 程序并得到 Segmentation fault: 11

#include <stdio.h>
#include <stdlib.h>

#define SIZE 2

void print_array(double **arr, int size) {
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%f\n", arr[i][j]);
        }
    }
}

int main(int argc, char **argv) {
    double mat[SIZE][SIZE] = {{1, 2}, {3, 4}};
    print_array((double **) mat, SIZE);
}

有人可以解释为什么会这样吗?我不认为我需要为 mat 动态分配内存,因为我将它传递给 print_array within main() 函数。

print_array()的函数签名更改为

void print_array(int size, double arr[size][size])

问题消失了。

不过还是很好奇...为什么在将 mat 转换为 double ** 并将其传递给 print_array() 时出现分段错误?归根结底,大小为 2 的 double arr[2][2]double **arr 是一回事,对吗?

你得到了未定义的行为,因为你对编译器说谎你的内存包含什么。

mat 的内存格式与 (double **) 不同。前者是doubles的紧凑方块,后者是指向指针的指针。这些不一样。

您可以将 2D 表示为行(或列,如果您愿意)指针数组,这使得双索引工作。但这与索引实际数组不同。

更新:我不确定是否有可能为可以访问实际紧凑数组或通过指针表示的函数提供函数签名。 .. 我的建议是保持简单并为这些不同的要求编写两个不同的函数:

void print_matrix_compact(const double *el0, size_t size);
void print_matrix_indirect(const double **mtx, size_t size);

这里 el0 是指向实际 ("compact") 数组的元素 0 的指针,而 mtx 是指向存储为数组的指针数组的指针数组。在这两种情况下,矩阵都假定为正方形,大小为 size×size 个元素。

不,它们不一样。

A double[size][size] 是包含 double 的连续内存块,编译器知道如何从索引中计算地址。

A double ** 是一个指向包含一个或多个指向 double 块的内存块的指针。

通过将 double[size][size] 作为 double ** 访问,您将 double 值解释为指针。