C将指针传递给函数的指针并使用malloc [英] C Passing Pointer to Pointer to a Function and Using malloc

查看:50
本文介绍了C将指针传递给函数的指针并使用malloc的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图获取std输入以扫描两个 x 行(x <100)和 y 列的两个二维并行数组(arrAtk,arrDef)(y <1,000,000).但是 y 在每一行中都是可变长度.

I'm trying to get std input to scan in two 2d parallel arrays (arrAtk, arrDef) of x rows (x<100), and y columns (y<1,000,000). But y is a variable length in each row.

输入的第一行是 x ,表示每个数组中的行数.第二行是 y ,表示第一行的列数.接下来是要读入arrAtk数组的 y 个整数.然后再将另一个 y 整数读取到arrDef数组中.紧随其后的是后面两行中的列数的整数 y .依此类推.

The first line of input is x for the number of rows in each array. the second line is y for the number of columns in the first row. Following that is y integers to be read into the arrAtk array. Then another y integers to be read into the arrDef array. Directly following is an int y for the number of columns in the next two rows. And so on.

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

The parallel arrays will hold integers that will be sorted later, and each parallel element will be compared to see which of the rows had higher numbers.

问题:因此,我尝试使用函数调用扫描输入,并动态分配正确的内存量,并扫描2d数组每一行的输入.这似乎工作正常,但是当我尝试在main中打印数组值时,它崩溃了.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

代码:

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

推荐答案

虽然有更好的方法可以执行此操作,但是可以采用您所采用的方法来完成.首先要注意的是,您正在将每个指针传递给函数,而不是指针的地址.发生这种情况时,您的函数将收到指针的 副本,其中包含值的正确地址(如果已初始化),但其自身的完全不同的地址.

While there are better ways of doing this, it can be done with the approach you have taken. The first thing to note is you were passing each pointer to your function instead of the address of the pointer. When that occurs, your function receives a copy of the pointer, containing the proper address for the values (if initialized), but with a very different address of its own.

因此,当您为函数中的每个数组分配存储空间时, main 中的指针是完全不变的.他们仍然没有指向.为了使分配反映在 main 中,您必须将指针的地址传递给函数,并在函数中进行相应的取消引用,以便在<代码>主要.

So when you allocate storage for each of your arrays in the function, the pointers in main are completely unchanged. They still point to nothing. In order to have the allocations reflected in main you must pass the address of the pointer to your function, and dereference accordingly in your function, so that the allocations are available in main.

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

The short version is you need to call your function with scanIn (&arrAtk, &arrDef, &armies) and your prototype must be (int***, int***, int**). (not particularly attractive)

另一个问题是,C语言中的 style 通常避免使用 caMelCase 变量(C语言则不使用).请参阅:(第2.2节) NASA C样式指南 (Goddard航天中心1994)

One other issue is that style in C generally avoids the use of caMelCase variables (leave that for C++). See: (section 2.2) NASA C Style Guide (Goddard Spaceflight Center 1994)

以下是使分配按预期工作所需的附加间接级别的示例.(注意:您还应该释放分配的内存):

Below is an example of the additional level of indirection required to make the allocation work as you intended. (note: you should also free the memory you allocate):

#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 .考虑到这一点,您的 main scan_in 代码如下所示:

note: since you are new to C, there are a few more areas where you can improve your code: (1) always initialize your variables that are not explicitly assigned a value in your code; (2) always validate the return values from the functions you call; and (3) always keep track of, and free the memory you allocate when it is no longer needed. Taking that into consideration, your main and scan_in code would look like:

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

这篇关于C将指针传递给函数的指针并使用malloc的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆