按引用调用失败

call by reference failure

提问人:Niv Turk 提问时间:5/23/2022 更新时间:5/23/2022 访问量:47

问:

我有一个任务需要处理由 typedef 定义的 4X4 矩阵。 任务是在 main 中为声明的矩阵创建一个计算器,并解释用户以简单单词形式传递的命令。问题是我试图在使用它的函数之间传递矩阵地址。

int main(){

mat MAT_A,MAT_B,MAT_C,MAT_D,MAT_E,MAT_F; 
printf("MAT_A is at-%p\n",(void*)&MAT_A);
read_command(&MAT_A,&MAT_B,&MAT_C,&MAT_D,&MAT_E,&MAT_F);
}

在这个函数中,我将矩阵解释为作为值传递给计算函数str_to_arg将 mat* 作为参数传递给add_mat函数

void read_command(mat *a,mat *b,mat *c,mat *d,mat *e,mat *f){
add_mat((str_to_arg(a,b,c,d,e,f,strtok(NULL,","))),(str_to_arg(a,b,c,d,e,f,strtok(NULL,","))),(str_to_arg(a,b,c,d,e,f,strtok(NULL,","))));
printf("mat added at %p\n",(void*)a);
}

add_mat函数接收 3 个 mat* 作为参数

void add_mat(mat *a, mat *b , mat *c){
int i,j;
double sum;
for(i=0 ; i<MAT_LENGTH ; i++){
    for(j=0;j<MAT_LENGTH; j++){
        sum = *a[i][j]+ *b[i][j];
        *c[i][j]=sum;
        
    }
}   

printf("add succeed to matrix at adress %p\n",(void*)*c);
print_mat(*c);
}

正如你所看到的,我在任何给定时间都添加了 3 个打印件来跟随地址,main 和 read_command 处的矩阵地址相同,但add_mat中的地址不同。

我尝试过许多组合,包括将指针传递到指针,但似乎没有任何东西将正确的地址传递给add_mat因此实际矩阵的值不会改变。

感谢您的帮助。

c 内存地址 按值调用

评论

1赞 Goswin von Brederlow 5/23/2022
未指定函数参数的计算顺序。因此,您键入的第一个字母可以指定第 3 个参数,下一个是第 1 个参数,下一个是第 2 个参数或任何其他顺序。首先按定义的顺序解析输入,然后调用 。add_mat()
0赞 Goswin von Brederlow 5/23/2022
*a[i][j]不会按照你的想法去做。它需要 ,然后向前跳过,然后查找其中的行号,最后取消引用该行,这意味着使用该行的第一列。你是说吗?aimatjmat(*a)[i][j]
0赞 Niv Turk 5/23/2022
意思是查看作为“A”传递的矩阵的 i,j 值。这似乎不是问题,因为计算的值是正确的。主要问题是矩阵 (c) 不是所需的实际地址。如果我直接从main执行Add_mat(),这就可以了。(无论如何,我可能不需要传递 mat a、mat b 作为指针,因为我只是使用它们包含的值)。
0赞 Goswin von Brederlow 5/23/2022
如果从 main 执行,则没有 UB from 。add_matread_command
0赞 Nate Eldredge 5/23/2022
请创建一个最小的可重现示例。这意味着一个完整的程序无需进一步编辑即可编译和运行,并删除所有不相关的功能。特别是,如何定义,它是否返回指向具有足够生存期的可写对象的指针?(如果是这样,您可能仍然有内存泄漏。str_to_argmat

答:

1赞 tstanisl 5/23/2022 #1

取消引用指向 2d 数组的指针应通过以下方式完成:

(*a)[i][j]

原因是索引运算符的优先级高于 。[]*

函数应为:add_mat()

void add_mat(mat *a, mat *b , mat *c){
int i,j;
double sum;
for(i=0 ; i<MAT_LENGTH ; i++){
    for(j=0;j<MAT_LENGTH; j++){
        sum = (*a)[i][j]+ (*b)[i][j];
        (*c)[i][j]=sum;
        
    }
}