3

我正在尝试在 C 中实现我自己的基本版本的矩阵乘法,并基于另一种实现,我制作了一个矩阵数据类型。该代码有效,但作为 C 新手,我不明白为什么。

问题:我有一个结构,里面有一个动态数组,我正在初始化指针。见下文:

// Matrix data type
typedef struct
{
    int rows, columns;      // Number of rows and columns in the matrix
    double *array;          // Matrix elements as a 1-D array
} matrix_t, *matrix;

// Create a new matrix with specified number of rows and columns
// The matrix itself is still empty, however
matrix new_matrix(int rows, int columns)
{
    matrix M = malloc(sizeof(matrix_t) + sizeof(double) * rows * columns);
    M->rows = rows;
    M->columns = columns;
    M->array = (double*)(M+1); // INITIALIZE POINTER
    return M;
}

为什么我需要将数组初始化为 (double*)(M+1)?似乎 (double*)(M+100) 也可以正常工作,但是当我运行矩阵乘法函数时,例如 (double *)(M+10000) 不再有效。

4

3 回答 3

3

这种东西的推荐方法是与offsetof. 它确保正确对齐。

#include <stddef.h>
#include <stdlib.h>

// Matrix data type
typedef struct s_matrix
{
    int rows, columns;      // Number of rows and columns in the matrix
    double array[];         // Matrix elements as a 1-D array
} matrix;

// Create a new matrix with specified number of rows and columns
// The matrix itself is still empty, however
matrix* new_matrix(int rows, int columns)
{
    size_t size = offsetof(matrix_t, array) + sizeof(double) * rows * columns;
    matrix* M = malloc(size);
    M->rows = rows;
    M->columns = columns;
    return M;
}
于 2013-09-06T10:02:09.030 回答
2

M+1指向紧随其后的内存M(即在两个int和之后double*)。这是您为矩阵数据分配的内存:

matrix M = malloc(sizeof(matrix_t) + sizeof(double) * rows * columns);
                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

使用M+100orM+10000然后尝试填充矩阵将导致未定义的行为。这可能会导致程序崩溃,或者程序似乎可以工作(但实际上已损坏),或者介于两者之间。

于 2013-09-06T09:43:54.213 回答
0

您需要初始化它,否则(等待它)它是未初始化的!

并且您不能将未初始化的指针用于任何事情,除非生成未定义的行为。

将其初始化M + 1完全正确且非常好的代码。任何其他值都无法使用您为此确切目的分配的内存。

我的观点是double *struct 的末尾不会“自动”指向此内存,这是您对为什么应该初始化它的问题的隐含信念。因此,必须将其设置为正确的地址。

于 2013-09-06T09:47:42.087 回答