简要说明:如果你想测试代码,你可以在GitHub上找到Gist: https://gist.github.com/nok/c0ff77db0513384fcbbd
我们有一套已知的论文。类型Paper
的每篇论文都有Matrix
类型的x矩阵。我们想要动态存储一系列论文并从其他函数中读取这些论文。这是数据结构:
typedef struct Matrix {
int rows;
int cols;
float** data;
} Matrix;
typedef struct Page {
char id; // unique id
int size; // size of matrices
Matrix** matrices;
} Page;
我们使用以下函数创建了必需的结构(删除了错误处理):
Matrix *new_matrix(int n_rows, int n_cols, float** data)
{
Matrix *M = (Matrix *) malloc(sizeof(Matrix));
M->rows = n_rows;
M->cols = n_cols;
M->data = (float **) malloc(M->rows * sizeof(float *));
int i;
for (i = 0; i < M->rows; i++) {
M->data[i] = data[i];
}
return M;
};
Page *new_page(int id, int n_size, Matrix** data)
{
Page *P = (Page *) malloc(sizeof(Page));
P->id = id;
P->size = n_size;
int i;
P->matrices = malloc(n_size * sizeof(Matrix));
for (i = 0; i < n_size; ++i) {
P->matrices[i] = data[i];
}
return P;
};
现在,我们想要在单独的函数app_init
中分配内存:
Page **pages; // <--------------
int main(void) {
app_init();
app_update();
return EXIT_SUCCESS;
}
void app_init() {
pages = (Page **) malloc(2 * sizeof(Page *));
Matrix* m1 = new_matrix(3, 5, (float*[5]) {
(float[5]) { 111, 112, 113, 114, 115 },
(float[5]) { 121, 122, 123, 124, 125 },
(float[5]) { 131, 132, 133, 134, 135 },
});
Matrix* m2 = new_matrix(3, 4, (float*[4]) {
(float[4]) { 211, 212, 213, 214 },
(float[4]) { 221, 222, 223, 224 },
(float[4]) { 231, 232, 233, 234 },
});
pages[0] = (Page *) new_page(1, 2, (Matrix*[2] ) { m1, m2 });
Matrix* m3 = new_matrix(3, 5, (float*[5]) {
(float[5]) { 311, 312, 313, 314, 315 },
(float[5]) { 321, 322, 323, 324, 325 },
(float[5]) { 331, 332, 333, 334, 335 },
});
Matrix* m4 = new_matrix(3, 4, (float*[4]) {
(float[4]) { 411, 412, 413, 414 },
(float[4]) { 421, 422, 423, 424 },
(float[4]) { 431, 432, 433, 434 },
});
pages[1] = (Page *) new_page(2, 2, (Matrix*[2] ) { m3, m4 });
}
(我想在变量pages
中存储所有页面时会出现问题。)
然后我们想查看所有论文的所有矩阵:
void app_update() {
int i, j;
for (i=0; i<NUMBER_PAGES; i++){
printf("Page (%d): %d\n", i, pages[i]->id);
for(j=0; j<pages[i]->size; j++){
printf("Matrix (%d):\n", j);
print_matrix(
pages[i]->matrices[j]->rows,
pages[i]->matrices[j]->cols,
(float *)pages[i]->matrices[j]->data[0]);
printf("\n---\n");
}
printf("\n------\n");
}
}
void print_matrix(int row, int col, float* data) {
int i, j;
for (i=0; i<row; i++){
for(j=0; j<col; j++){
printf("%.3f ", data[i*col+j]);
}
printf("\n");
}
}
阅读pages
的值在app_init()
范围内有效。但是在main()
和app_update()
的范围内,它失败了。我们如何永久存储这些值?
答案 0 :(得分:0)
app_init()
中传递给new_matrix()
的复合文字具有自动存储功能,app_init()
返回后将不再有效。因此,Matrix
类型中的指针将指向无效数据。
另外,传递给new_page()
的复合文字是非常量的,所以不是真正的文字。这是GCC扩展,不是C99语言的一部分。
此外,您的print_matrix()
函数将data
视为指向rows * cols
float
的连续块的指针,但您的Matrix
类型包含连续的指向rows
cols
s的连续块的float
指针块。
我建议您将data
类型的Matrix
成员和data
的{{1}}参数更改为new_matrix()
类型,更改{{1分配float*
malloc
的连续块,并将M->rows * M->cols
指针中的float
M->rows * M->cols
复制到float
。您需要将对data
的调用中的复合文字更改为M->data
的二维数组。实际上,您可能需要将其设置为1维以匹配new_matrix()
的参数,但您可以添加空格以使其显示为二维。