2017-09-25 51 views
2

我试图编写一个函数,要求用户输入矩阵。它提示的行数,列数,然后提示值矩阵中的每个元素:直到我进入一个价值i = 0然后按进入使用scanf for float **类型的分段错误

#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); 
} 

一切工作正常,从而导致分段故障。

任何想法可能是错的?

+2

'浮子*矩阵的计算[NBL * nbCol];'=>'浮子矩阵的计算[NBL * nbCol];'不需要指针。但你必须以某种方式将尺寸传递给'enterMatrix'。 –

+0

阅读关于通过VLA函数:https://stackoverflow.com/questions/14548753/passing-a-multidimensional-variable-length-array-to-a-function –

+2

什么是**矩阵**在enterMatrix函数? –

回答

2

您需要分配内存,因为您在编译时不知道变量nbLinesnbColumns将保持哪些值。

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

float **matrix; 

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

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

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

的分段错误发生becouse你不分配内存为您的矩阵,但只是一个[nbL * nbCol]指针float

+0

这个工作,谢谢! – AlexT

+1

这表明矩阵应该作为指针数组来实现,这并不好 - 它可能更好地实现矩阵作为动态分配的float数组。[ – anatolyg

+0

]另外,在C中,malloc()结果的类型转换是不是必需的(并且作为不好的技术被积极劝阻 - 如果'#include '已经被遗忘,那么转换就会掩盖AND而导致未定义的行为)。在'malloc()'调用中避免硬编码类型也被认为更好。使用'matrix = malloc(nbLines * sizeof(* matrix))'而不是'matrix = malloc(nbLines * sizeof(float *))',因为如果'matrix'的定义发生变化,后者将会中断...比如一个'双**'。 – Peter

3

您的问题是因为

float *matrice[nbL * nbCol]; 

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

一个补丁修复将是main()改变matrice的定义

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

你不为你的数组分配足够的内存,因此你调用了Undefined Behavior,因为你超出了界限,导致了分段错误。

你可以宣布它像一个二维数组,像这样:

/* 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)); 

我有一个动态分配here一个二维数组的其他方法。请注意:Do I cast the result of malloc?不!

也别忘了free()


你可以模拟一个二维数组与一维数组,像这样:

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]; 
1

你要创建一个可变长度的数组,中,指针

而其他的答案是完全有效的,如果你真的一个二维数组,你只需要改变声明:

float matrix[nbLines][nbColumns]; 

申报花车的二维变长数组。

现在的难点是将这个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); 
+0

@ M.M我修正了一个问题:声明。我的眼睛首先欺骗了我......是的,也是'scanf'的论点......感谢回复! –

+0

请注意,我的blurb不是很准确。感谢您指出这些错误。 –