【问题标题】:Segmentation fault when printing contents of a multidimensional array打印多维数组的内容时出现分段错误
【发布时间】:2015-09-17 07:37:12
【问题描述】:

我正在运行以下 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 main() 函数中。

print_array()的函数签名更改为

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

问题消失了。

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

【问题讨论】:

    标签: c pointers syntax segmentation-fault


    【解决方案1】:

    由于您在内存包含的内容上向编译器撒谎,因此您得到了未定义的行为。

    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 是指向实际(“紧凑”)数组的元素0 的指针,而mtx 是指向存储为数组数组的指针数组的指针。在这两种情况下,矩阵都假定为正方形,大小为size×size 个元素。

    【讨论】:

    • 我现在明白了——谢谢你的回答。我正在使用此函数打印存储在函数内堆栈中的方阵的内容,以及使用 malloc 调用打印初始化为double **mat 的数组的内容。我怎样才能对两者使用相同的功能?正如我所提到的,将 print 函数的签名更改为接受 arr[size][size] 以及 size 参数就可以了,但我觉得如果尝试使用该新函数打印存储为 @ 的数组,我会遇到同样的问题987654331@s,因为他们不会连续存储双打。
    • arr 的实际类型,当声明为 double arr[size][size] 并传递给函数时是 double[][size]。这些函数需要double*。你正确地调用它:print_matrix_compact(&amp;arr[0][0], size);
    【解决方案2】:

    不,它们不一样。

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

    double ** 是一个指向内存块的指针,其中包含一个或多个指向doubles 块的指针。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-02-16
      • 2013-11-10
      • 2015-02-08
      • 2019-08-03
      • 1970-01-01
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多