使用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);