【问题标题】:Segmentation fault in passing multidimensional arrays to functions in C将多维数组传递给 C 中的函数时出现分段错误
【发布时间】:2019-04-20 04:42:17
【问题描述】:

我们在介绍中看到使用指针将数组传递给函数。到 C 类,我正在尝试学习如何自己传递多维数组。我尝试编写一个函数来将矩阵条目的值分配给本地数组,但出现分段错误。我希望有人能解释为什么会发生这种情况以及如何解决它。我在 macOS Sierra 上使用终端。提前致谢。我的代码如下:

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

void fillMatrix();

int main(void){
    int rows, cols;

    printf("\nEnter the number of columns:\n");
        scanf("%d", &cols);
    printf("\nEnter the number of rows:\n");
        scanf("%d", &rows);

    int matrix[rows][cols];


    fillMatrix(&matrix[rows][cols], rows, cols);

    for (int i = 0; i < rows; ++i){
        for (int j = 0; j < (cols - 1); ++j){
            printf("%d ", matrix[i][j]);
        } printf("%d\n", matrix[i][(cols -1)]);
    }
    return 0;
}

void fillMatrix( int *matrix, int rows, int cols ){
    for (int i = 0; i < rows; ++i){
        for (int j = 0; j < cols; ++j){
            printf("\nPlease enter the A(%d,%d) entry:\n", i, j);
                scanf("%d", &*(matrix + (i*cols) + j));
        }
    }
    return;
}

【问题讨论】:

    标签: c macos segmentation-fault


    【解决方案1】:

    鉴于声明

    int matrix[rows][cols];
    

    这段代码是错误的:

    fillMatrix(&matrix[rows][cols], rows, cols);
    

    &amp;matrix[rows][cols] 的地址超出了矩阵的末尾。

    矩阵的第一个元素是&amp;matrix[0][0],矩阵的最后一个元素是&amp;matrix[rows-1][cols-1]。

    还有这个声明

    void fillMatrix();
    

    会导致这个定义出现问题:

    void fillMatrix( int *matrix, int rows, int cols ){
        ...
    

    他们需要匹配。现在,由于上面的void fillMatrix() 声明,参数通过default argument promotion 传递给函数,但是由于定义 具有显式参数,函数本身期望参数作为@ 传递987654330@ 或int。您可能对此没有问题,因为这些参数的默认值可能与这些参数相同,但函数定义和声明通常必须完全匹配。

    我没有检查您的代码是否存在其他问题。

    【讨论】:

    • 谢谢你修复它!我对复制粘贴没有考虑或检查两次感到内疚。 “你可以在七分钟内接受答案”
    • @AlexD 我也注意到了别的东西。您的函数定义和声明与 fillMatrix() 不匹配。
    【解决方案2】:

    在 C 中,当你声明一个数组时,你需要在编译时指定它的大小。当你在队列中减速时

        int matrix[rows][cols];
    

    你实际上用垃圾值初始化它的大小。在我的编译器的情况下,它被初始化为 [0][0] 的大小。为了实现您想要的,您需要做以下两件事之一:

    1. 在编译前明确指定数组的大小
    2. 为数组动态分配空间

    【讨论】:

    • “你需要在编译时指定它的大小”——自从 C99 以来就不是这样了,增加了可变长度数组,这些数组在运行时调整大小(尽管这些在 C11 中再次成为可选的, VLA 几乎无处不在)。此外,rows 和 cols 在 OP 代码中没有垃圾值,除非用户输入错误(因此 OP 应该在使用之前验证输入以避免未定义的行为。)
    猜你喜欢
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    • 2023-03-08
    • 2020-08-27
    • 1970-01-01
    • 2021-03-12
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多