使用scanf对浮点**型进行分段故障

使用scanf对浮点**型进行分段故障,c,pointers,matrix,segmentation-fault,scanf,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);

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

#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);
}
float **matrix;
#包括
#包括
无效输入矩阵(浮点**矩阵、整数行、整数列){
对于(int i=0;i
一切正常,直到我为
I=0输入一个值,然后按enter键,这会导致分段错误


你知道哪里会出错吗?

你需要手动分配内存,因为你在编译时不知道变量
nbLines
nbColumns
会保存哪些值

因此,您需要首先声明指向矩阵的指针:

#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);
}
float **matrix;
然后开始根据用户输入分配内存:

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

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

分段错误的发生是因为您没有为矩阵分配内存,而只是一个指向浮点的指针

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

一种修复方法是将
main()
matrice
的定义更改为

float matrice[nbL * nbCol];
并将函数更改为(我已使用注释突出显示更改)

void enterMatrix(float*矩阵、int-nbline、int-nbColumns)/*注意矩阵的类型*/
{
对于(int i=0;i
您没有为数组分配足够的内存,因此调用了未定义的行为,因为您超出了界限,导致了分段错误

您可以将其声明为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));
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];

您正在创建一个可变长度的指针数组和

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

float matrix[nbLines][nbColumns];
声明浮动的二维可变长度数组

现在的难点是将这个VLA传递给一个函数并保留维数

为此,您可以使用C99通过VLA的方式(请注意,尺寸必须位于VLA本身之前)。参考资料:


float*矩阵[nbL*nbCol]=>
浮点矩阵[nbL*nbCol]不需要指针。但是您必须以某种方式将维度传递给
enterMatrix
。阅读有关将VLA传递给函数的内容:enterMatrix函数中的矩阵是什么?当您翻译代码时,请在编译时使其保持原样:)请注意
scanf()
如果输入未按预期类型解析,则可能会失败。检查返回值是一个好主意。这表明矩阵应该实现为指针数组,这并不好——最好将矩阵实现为动态分配的
float
数组。此外,在C中,不需要
malloc()
结果的类型转换(并被积极劝阻为糟糕的技术-如果忘记了
#include
,转换会掩盖这一点,并导致未定义的行为)。还认为最好避免在
malloc()
调用中硬编码类型,例如使用
matrix=malloc(nbLines*sizeof(*matrix))
而不是
矩阵=malloc(nbLines*sizeof(float*))
因为如果矩阵的定义发生变化,
matrix
的定义就会被破坏……比如变成一个
double**
@M.M,我修正了一个问题:声明。我的眼睛一开始就欺骗了我……是的,还有
scanf
参数……谢谢回复!!注意我的宣传语不是很准确。谢谢你指出那些先生凯斯。
    enterMatrix(nbLines, nbColumns, matrix);