这是作业的一部分。
我目前在必须将.csv
文件读入以下结构的部分中:
typedef struct {
int n;
double **data;
} Matrix;
.csv
文件具有3行3列:
1 2 3
4 5 6
7 8 9
,看起来像是二维数组:
double array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
现在,我想像这样将我的数组分配给Matrix:
function someFunction(Matrix *m) {
//...
double array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
A->data = array;
A->n = 3;
//...
}
但是将array
分配给data
无效,因为使用gcc -Wall -pedantic-errors
时出现以下错误:
error: assignment to ‘double **’ from incompatible pointer type ‘double *’ [-Wincompatible-pointer-types]
79 | A->data = array;
如何解决此问题?部分分配是,在使用-Wall和-pedantic-erros时,不允许gcc显示任何警告,因此不允许黑客入侵。
答案 0 :(得分:3)
double**
是指向指针的指针。当然,(外部)指针也可以指向某个数组:
double* array[7];
double** pointer = array;
现在array
中的每个指针也可以指向其他数组:
double valueArray[12]
double* pointerArray[10];
double** pointer = array;
pointer[0] = valueArray; // equivalent to pointerArray[0] = ...
二维数组不是指针数组,但是,它们是数组数组,并且指向第一个元素的指针的类型不同:
double array[10][12];
double(*pointer)[12] = array;
尝试覆盖任意大小的矩阵会产生一些麻烦,但是:
struct Matrix
{
size_t n;
double(*data)[n]; // you cannot exchange arbitrary pointers,
// you need a compile time constant!
};
请注意,这与VLA的功能参数有所不同
void f(size_t n, int(*data)[n]);
然后看来,您所提供的一些代码已经很麻烦:
void someFunction(Matrix* m)
{
double array[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
m->data = array; // assuming you meant m instead of A
// and you did adjust the pointer type already appropriately
}
array
具有本地存储持续时间,如果您从函数返回后取消引用该指针,则从该函数返回后将立即销毁该指针,从而导致m
中的指针悬空并且行为不确定
因此,您需要malloc
足够大的数组。 但是也不要忘记再次释放它!
因此,如果您不想将指针指向指针方式:
double** array = malloc(sizeof(*array) * n);
array[0] = malloc(sizeof(**array) * n);
// ...
这将允许使用m->data[x][y]
语法,那么您应该坚持使用一维数组方法:
struct Matrix
{
size_t n;
double* data;
};
也许还有一些访问器功能:
double get(struct Matrix* m, size_t row, size_t column)
{
return m->data[row * m->n + column];
}
可以避免双指针间接访问,因此速度更快(实际上,这是在真正的二维数组的幕后进行的完全相同的计算,即不是指向指针变量的指针)。