[英]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
分配的内存。 考虑到这一点,您的main
和scan_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.