C将指针传递给指向函数的指针并使用malloc

时间:2016-03-07 20:52:27

标签: c arrays pointers malloc

我试图获取std输入来扫描 x 行(x <100)和 y 的两个2d并行数组(arrAtk,arrDef)列(y <1,000,000)。但 y 是每行的可变长度。

第一行输入是 x ,表示每个数组中的行数。 对于第一行中的列数,第二行是 y 。 接下来是 y 整数被读入arrAtk数组。 然后另一个 y 整数被读入arrDef数组。 对于接下来两行中的列数,直接跟随一个int y 。 等等。

并行数组将保存将在稍后排序的整数,并且将比较每个并行元素以查看哪些行具有更高的数字。

问题:因此我尝试使用函数调用扫描输入并动态分配正确的内存量并扫描2d数组的每一行的输入。 这似乎工作正常但是当我尝试在主要打印数组值崩溃时。 printf语句在scanIn函数中工作,所以我不能正确传递值。如何才能将它运用到我可以在函数外部使用动态创建的数组?

提前致谢

std输入示例:

2  //<- x num of rows 
2  //<- y num of cols
3 
6
5
2
3  //<- y num of cols
2
3
12
9
3
4

CODE:

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

int scanIn(int**,int**,int*);

int main(){
    int cases, *armies, **arrAtk, **arrDef;

    cases = scanIn(arrAtk,arrDef,armies);

    printf("%d\n",arrAtk[1][2]); // Should be 12 with above input
    printf("%d",arrDef[0][1]);   // Should be 2

    return 0;
}

int scanIn(int **arrAtk, int **arrDef, int *armies){
    int i, j, cases;

    scanf("%d",&cases);
    arrAtk = (int**)malloc(sizeof(int*)*cases);
    arrDef = (int**)malloc(sizeof(int*)*cases);
    armies = (int*)malloc(sizeof(int)*cases);

    for(i=0;i<cases;i++){
        scanf("%d",&armies[i]);
        arrAtk[i] = malloc(sizeof(int)*armies[i]);
        arrDef[i] = malloc(sizeof(int)*armies[i]);

        for(j=0;j<armies[i];j++){
            scanf("%d",&arrAtk[i][j]);
        }
        for(j=0;j<armies[i];j++){
            scanf("%d",&arrDef[i][j]);
        }
    }
    return (cases);
}

1 个答案:

答案 0 :(得分:1)

虽然有更好的方法可以做到这一点,但可以采用您采用的方法。首先要注意的是你将每个指针传递给你的函数而不是指针的地址。发生这种情况时,您的函数会收到指针的副本,其中包含值的正确地址(如果已初始化),但具有自己的非常不同的地址

因此,当您为函数中的每个数组分配存储时,main中的指针完全不变。他们仍然没有任何意义。为了使分配反映在main中,您必须将指向地址传递给您的函数,并在函数中相应地取消引用,以便{{1}中可以使用分配}。

简短版本是您需要使用main调用您的函数,并且您的原型必须是scanIn (&arrAtk, &arrDef, &armies)。 (不是特别有吸引力)

另一个问题是C中的 style 通常会避免使用(int***, int***, int**)变量(对C ++而言)。见:(第2.2节)NASA C Style Guide(Goddard Spaceflight Center 1994)

下面是使分配按预期工作所需的额外间接级别的示例。 (注意:你还应释放你分配的内存):

caMelCase

<强>输入

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

int scan_in (int***, int***, int**);

int main (void) {

    int cases, *armies, **arr_atk, **arr_def;

    cases = scan_in (&arr_atk, &arr_def, &armies);

    printf ("\n cases         : %d\n", cases);
    printf (" arr_atk[1][2] : %d\n", arr_atk[1][2]);
    printf (" arr_def[0][1] : %d\n\n", arr_def[0][1]);

    return 0;
}

int scan_in (int ***arr_atk, int ***arr_def, int **armies)
{    
    int i, j, cases;

    scanf ("%d",&cases);
    *arr_atk = malloc (sizeof **arr_atk * cases);
    *arr_def = malloc (sizeof **arr_def * cases);
    *armies = malloc (sizeof *armies * cases);

    for (i = 0; i < cases; i++) {
        scanf ("%d", &(*armies)[i]);
        (*arr_atk)[i] = malloc (sizeof ***arr_atk * (*armies)[i]);
        (*arr_def)[i] = malloc (sizeof ***arr_def * (*armies)[i]);

        for (j = 0; j < (*armies)[i]; j++) {
            scanf ("%d", &(*arr_atk)[i][j]);
        }
        for (j = 0; j < (*armies)[i]; j++) {
            scanf ("%d", &(*arr_def)[i][j]);
        }
    }
    return (cases);
}

<强>输出

$ cat ../dat/2dscan.txt
2
2
3
6
5
2
3
2
3
12
9
3
4

注意,因为您是C新手,还有一些可以改进代码的领域:(1)始终初始化未明确的变量在您的代码中分配了一个值; (2)始终验证您调用的函数的返回值;并且(3)始终跟踪,$ ./bin/2dscanin < ../dat/2dscan.txt cases : 2 arr_atk[1][2] : 12 arr_def[0][1] : 2 在不再需要时分配的内存。考虑到这一点,您的freemain代码将如下所示:

scan_in