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 に答える