使用scanf for float **类型的分段错误

时间:2017-09-25 11:55:39

标签: c pointers matrix segmentation-fault scanf

我试图编写一个要求用户输入矩阵的函数。它会提示行数,列数,然后提示矩阵的每个元素的值:

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

void enterMatrix(float ** matrix, int nbLines, int nbColumns){
    for (int i = 0; i < nbLines * nbColumns; i++){
        printf("i = %d? ", i);
        scanf("%f", matrix[i]);
    }
}

int main(void){
    int nbLines, nbColumns;
    printf("nbLines? "); scanf("%d", &nbLines);
    printf("nbColumns? "); scanf("%d", &nbColumns);
    float *matrix[nbL * nbCol];

    enterMatrix(matrix, nbLines, nbColumns);
}

一切正常,直到我输入i = 0的值,然后按输入,这会导致分段错误。

有什么可能出错的想法吗?

4 个答案:

答案 0 :(得分:3)

你的问题是因为

float *matrice[nbL * nbCol];

定义了一个未初始化的指针数组(即float *的数组),而不是float数组。然后将其作为指针指向enterMatrix()(即float)传递给float **scanf()调用然后读取到matrix[i],这是一个未初始化的指针。结果是未定义的行为。

一种解决方法是将matricemain()的定义更改为

float matrice[nbL * nbCol];

并将功能更改为(我已使用注释突出显示更改)

void enterMatrix(float *matrix, int nbLines, int nbColumns)    /*  note type of matrix  */
{
     for (int i = 0; i < nbLines * nbColumns; i++)
     {
         printf("i = %d? ", i);
         scanf("%f", &matrix[i]);      /*  note what the second argument is */
     }
}

答案 1 :(得分:2)

您需要以动态方式分配内存,因为您在编译时不知道变量nbLinesnbColumns将保留哪些值。

所以你需要先声明指向矩阵的指针:

float **matrix;

然后根据用户输入开始分配内存:

matrix = (float **)malloc(nbLines * sizeof(float *));

for (int i = 0; i < nbLines; i++)
{
    matrix[i] = (float *)malloc(nbColums * sizeof(float ));
}

因为您没有为矩阵分配内存而发生了分段错误错误,而只是指向[nbL * nbCol]的{​​{1}}指针

答案 2 :(得分:1)

您没有为数组分配足够的内存,因此您调用未定义的行为,因为您超出范围,导致分段错误。

您可以将其声明为2D数组,如下所示:

/* TODO: Check if allocation succeeded. (check for NULL pointer) */
float** matrix;
matrix = malloc(nbLines * sizeof(float*));
for(int i = 0 ; i < N ; i++)
    matrix[i] = malloc(nbColumns * sizeof(float));

我有其他动态分配2D数组的方法here

请注意:Do I cast the result of malloc?不!

另请不要忘记free()

您可以使用1D数组模拟2D数组,如下所示:

void enterMatrix(float* matrix, int nbLines, int nbColumns){
    for (int i = 0; i < nbLines ; i++) {
        for (int j = 0; j < nbColumns; j++) {
        scanf("%f", matrix[i + nbColumns * j]);
    }
}
float matrix[nbLines * nbColumns];

答案 3 :(得分:1)

您正在创建一个可变长度数组,以及指针

虽然其他答案完全有效,但如果你真的想要一个2D数组,你只需要更改声明:

float matrix[nbLines][nbColumns];

声明一个2D可变长度的浮点数组。

现在的难点在于将此VLA传递给函数并保留尺寸。

为此您可以使用C99方式传递VLA(请注意,尺寸必须位于VLA本身之前)。参考:Passing a multidimensional variable length array to a function

void enterMatrix(int nbLines, int nbColumns, float matrix[][nbColumns] ){
    for (int i = 0; i < nbLines; i++){
       for (int j = 0; j < nbColumns; j++)
   {            
        scanf("%f", &matrix[i][j]);
    }
  }
}

打电话如下:

    enterMatrix(nbLines, nbColumns, matrix);