我有一个返回逆矩阵的函数,如下所示:
double** inverse(double (**data)) {
double result[2][2];
result[0][0] = data[1][1] / (data[0][0] * data[1][1] - data[0][1] * data[1][0]);
result[0][1] = -data[0][1] / (data[0][0] * data[1][1] - data[0][1] * data[1][0]);
result[1][0] = -data[1][0] / (data[0][0] * data[1][1] - data[0][1] * data[1][0]);
result[1][1] = data[0][0] / (data[0][0] * data[1][1] - data[0][1] * data[1][0]);
return result;
}
我已经检查了结果中的值,他们是对的。然后:
double** s = inverse(gama[FreIdx]);
printf("%f\n", s[0][0]);
我得到了例外。读取位置0x0时发生访问冲突......我对C不是很熟悉。有谁能告诉我发生了什么?
答案 0 :(得分:1)
您正在静态地在逆内部创建矩阵,这意味着它将驻留在该函数调用的堆栈帧内。然后返回该矩阵的地址,但只要返回该函数,就可以覆盖它的堆栈帧 您需要动态分配矩阵,并记住在不需要时立即释放它。
?
释放它:
&
注意:最好创建一个析构函数来处理释放内部数组和外部数组的问题。在double** inverse(double data[][2]) {
double **result = malloc(sizeof(double*) * 2);
result[0] = malloc(sizeof(double) * 2);
result[1] = malloc(sizeof(double) * 2);
result[0][0] = data[1][1] / (data[0][0] * data[1][1] - data[0][1] * data[1][0]);
result[0][1] = -data[0][1] / (data[0][0] * data[1][1] - data[0][1] * data[1][0]);
result[1][0] = -data[1][0] / (data[0][0] * data[1][1] - data[0][1] * data[1][0]);
result[1][1] = data[0][0] / (data[0][0] * data[1][1] - data[0][1] * data[1][0]);
return result;
}
(您刚刚释放)中添加NULL也是一种很好的做法,以便在免费后捕获潜在用法。
答案 1 :(得分:1)
double **inv = inverse(mat);
free(inv[0]);
free(inv[0]);
free(inv);
来自inv
函数的return
调用未定义的行为(see here for details)。
从那时起可能发生任何事情。
认真对待编译器的警告。
更糟糕的是,double[2][2]
生活在double**
函数的堆栈上,并且在函数返回时已经死了。