C

时间:2017-12-30 11:38:34

标签: c pointers segmentation-fault parameter-passing

我正在使用动态初始化来生成两个矩阵。但问题是我的调试器在函数" printArray"中给出了错误。任何人都可以帮助我为什么会这样。我昨天刚刚学会了动态初始化。

在主函数中,我从用户那里获取关于矩阵维数的输入,你可以观察到在这些输入的基础上我能够动态指定矩阵的维数。

#include <stdio.h>
#include <stdlib.h>
int Function(int [], int , int);
void printArray(int **Matrix, int row, int column);

int row = 0, col = 0;
int **P = 0;

int main() {


    printf("Give me Dimensions of Matrix 1 : : ");
    printf("No .of Rows : ");
    scanf_s("%d", &row);
    printf("No .of Columns : ");
    scanf_s("%d", &col);

    Function(P, row, col);
    printArray(P, row, col);

    printf("Give me size of Matrix 2 : ");
    printf("No .of Rows : ");
    scanf_s("%d", &row);
    printf("No .of Columns : ");
    scanf_s("%d", &col);
    Function(P, row, col);
    printArray(P, row, col);
    system("pause");
    return 0;
}

int Function(int **A, int s, int c) {
    A = malloc(row * sizeof(int *));
    for (int i = 0; i < row; i++) A[i] = malloc(col * sizeof(int *));

    for (int i = 0; i < s; i++) {

        for (int j = 0; j < c; j++) {

            A[i][j] = rand() % 10;
        }
    }
}


void printArray(int **Matrix, int row, int column) {


    for (int i = 0; i < row; i++) {

        for (int j = 0; j < column; j++) {

            printf("%d ", Matrix[i][j]);
        }

        puts("");
    } 

    puts("");

}

2 个答案:

答案 0 :(得分:0)

  1. 在这种情况下,主要问题是 - C是按值传递的,当您将其传递给函数时,您没有对全局变量进行任何更改 - 而是更改了局部变量 - 本地变量函数Function。要对其进行更改,您需要传递它的地址。然后通过解除引用它,您将对实际变量进行更改。
  2. 除非你有一些有效的东西从函数返回,否则返回类型为void

    例如:(插图目的)

    Function(&P, row, col);
    
    ...
    void Function(int ***A, int s, int c) {
        (*A) = malloc(s * sizeof(int *));
        for (int i = 0; i < s; i++) (*A)[i] = malloc(c * sizeof(int));
    
        for (int i = 0; i < s; i++) {
    
            for (int j = 0; j < c; j++) {
    
                (*A)[i][j] = rand() % 10;
            }
        }
    
    }
    

    还要注意

    A[i] = malloc(col * sizeof(int *));
    

    将是

    (*A)[i] = malloc(col * sizeof(int ));
                                 ^^^^^
    

    您需要为之前未提及的int变量分配内存。

    1. 检查mallocscanf的返回值。例如:

      (*A) = malloc(row * sizeof(int *));
      if( (*A) == NULL){
        perror("Malloc failed");
        exit(EXIT_FAILURE);
      }
      
    2. 和 -

          if( scanf_s("%d", &row)!= 1){
            fprintf(stderrm,"Error in input");
            exit(EXIT_FAILURE);
          }
      
      1. 在函数Function内(我会说错误命名),您正在使用全局变量row。这是一种不好的做法,对代码可读性和可维护性也存在问题。调试更加困难。

答案 1 :(得分:0)

函数的参数是它的局部变量。您可以通过以下方式想象您的函数定义及其调用

int **P = 0;
Function(P, row, col);

//...

int Function( /*int **A, int s, int c*/) {
    int **A = P;
    int s = row;
    int c = col;

    A = malloc(row * sizeof(int *));
    //...
}

因此可以看出函数中的函数参数A已被更改。原始参数P在函数中未更改。这就是函数处理原始参数的副本。

您应该通过引用传递参数,如

int **P = 0;
Function( &P, row, col);

//...

int Function( int ***A, int s, int c) {
    *A = malloc(row * sizeof(int *));
    //...
}

或从函数返回创建的指针。例如

int **P = 0;
P = Function( row, col);

//...

int ** Function( int s, int c) {
    int **A = malloc(row * sizeof(int *));
    //...
    return A;
}

考虑到函数的返回类型为int,但不返回任何内容。

这也是一个错误,而不是参数,函数使用函数中的gobal变量行,例如

for (int i = 0; i < row; i++) A[i] = malloc(col * sizeof(int *));
                ^^^^^^

另外你应该释放分配的内存。否则程序中会出现内存泄漏。