簡體   English   中英

C將指針傳遞到函數的指針並使用malloc

[英]C Passing Pointer to Pointer to a Function and Using malloc

我正在嘗試獲取std輸入以掃描x行(x <100)和y列(y <1,000,000)的兩個2d並行數組(arrAtk,arrDef)。 但是y在每一行中都是可變長度。

輸入的第一行是x ,表示每個數組中的行數。 第二行是y ,表示第一行的列數。 接下來是y個要讀取到arrAtk數組中的整數。 然后再將另外y個整數讀入arrDef數組。 直接下面是列在接下來的兩行中的數字的int 收率 等等。

並行數組將保存將在以后排序的整數,並且將比較每個並行元素以查看哪些行的編號更高。

問題:因此,我試圖通過函數調用掃描輸入,並動態分配正確的內存量,並掃描2d數組每一行的輸入。 這似乎工作正常,但是當我嘗試在main中打印數組值時,它崩潰了。 printf語句在scanIn函數中起作用,因此我不能正確傳遞值。 我如何才能在函數外部使用動態創建的數組?

提前致謝

標准輸入示例:

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

碼:

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

盡管有更好的方法可以執行此操作,但是可以采用您采用的方法來完成。 首先要注意的是,您正在將每個指針傳遞給函數,而不是指針的地址 發生這種情況時,您的函數將收到一個指針副本 ,其中包含值的正確地址(如果已初始化),但其自身的地址非常不同

因此,當您為函數中的每個數組分配存儲空間時, main中的指針完全不變。 他們仍然沒有指向。 為了使分配反映在main您必須將指針的地址傳遞給函數,並在函數中進行相應的取消引用,以便可以在main中使用分配。

簡短的版本是您需要使用scanIn (&arrAtk, &arrDef, &armies)調用函數,並且原型必須為(int***, int***, int**) (不是特別有吸引力)

另一個問題是,C語言中的樣式通常避免使用caMelCase變量(而C語言caMelCase使用)。 參見:(第2.2節) NASA C樣式指南 (Goddard Spaceflight Center 1994)

以下是使分配按預期工作所需的附加間接級別的示例。 (注意:您還應該釋放分配的內存):

#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

產量

$ ./bin/2dscanin < ../dat/2dscan.txt

 cases         : 2
 arr_atk[1][2] : 12
 arr_def[0][1] : 2

注意:由於您不熟悉C,因此還有很多地方可以改進代碼: (1)始終初始化未在代碼中明確分配值的變量; (2)始終驗證您調用的函數的返回值; (3)始終跟蹤並在不再需要時free分配的內存。 考慮到這一點,您的mainscan_in代碼如下所示:

int main (void) {

    int i, cases = 0, *armies = NULL, **arr_atk = {NULL}, **arr_def = {NULL};

    if ((cases = scan_in (&arr_atk, &arr_def, &armies)) < 1) {
        fprintf (stderr, "error: invalid value for cases returned.\n");
        return 1;
    }

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

    for (i = 0; i < cases; i++) { /* free allocated memory */
        if (arr_atk[i]) free (arr_atk[i]);
        if (arr_def[i]) free (arr_def[i]);
    }
    if (arr_atk) free (arr_atk);
    if (arr_def) free (arr_def);
    if (armies)  free (armies);

    return 0;
}

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

    if (scanf ("%d",&cases) != 1) {
        fprintf (stderr, "scan_in() error: input failure.\n");
        return 0;
    }
    *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++) {
        if (scanf ("%d", &(*armies)[i]) != 1) {
            fprintf (stderr, "scan_in() error: input failure.\n");
            return 0;
        }
        (*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++) {
            if (scanf ("%d", &(*arr_atk)[i][j]) != 1) {
                fprintf (stderr, "scan_in() error: input failure.\n");
                return 0;
            }
        }
        for (j = 0; j < (*armies)[i]; j++) {
            if (scanf ("%d", &(*arr_def)[i][j]) != 1) {
                fprintf (stderr, "scan_in() error: input failure.\n");
                return 0;
            }
        }
    }
    return (cases);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM