将数组分配给双指针

时间:2020-01-14 09:28:32

标签: c pointers

这是作业的一部分。 我目前在必须将.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显示任何警告,因此不允许黑客入侵。

1 个答案:

答案 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];
}

可以避免双指针间接访问,因此速度更快(实际上,这是在真正的二维数组的幕后进行的完全相同的计算,即不是指向指针变量的指针)。