如何将从 hdf5 文件中读取的多个数据存储在一个数组中?
How do I store multiple data read from hdf5 files in one array?
我正在尝试从 HDF5 文件中预加载一堆矩阵并将它们存储在一个动态数组中。但是,我无法让它像我希望的那样工作。
由于某种我无法弄清楚的原因,整个数组被覆盖而不是子数组。有什么解决办法吗?
这是我的代码:
short ***data[line_count];
short** dset_data;
for (int file_index = 0; file_index < line_count; ++file_index){
dset_data = (short**) malloc(DIM_Y * sizeof(short*));
dset_data[0] = (short*) malloc(DIM_Y * DIM_X * sizeof(short));
for (int i=1; i < DIM_Y; i++)
dset_data[i] = dset_data[0] + i * DIM_X;
for (int y = 0; y < DIM_Y; y++) {
for (int x = 0; x < DIM_X; x++) {
dset_data[y][x] = 0;
}
}
/* Open an existing file. */
file_id = H5Fopen(input_files[file_index], H5F_ACC_RDONLY, H5P_DEFAULT);
/* Open an existing dataset. */
dataset_id = H5Dopen2(file_id, "data/data", H5P_DEFAULT);
/* Read dataset */
status = H5Dread(dataset_id, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &dset_data[0][0]);
/* Store two dimensional array at n-th position in data array */
data[file_index] = &dset_data;
/* Close the dataset. */
status = H5Dclose(dataset_id);
/* Close the file. */
status = H5Fclose(file_id);
}
将评论减去对三星级数据的下意识反应,转化为答案。
data
的声明:
short ***data[line_count];
和分配给它的行:
data[file_index] = &pset_data;
是麻烦的根源。您在每次迭代中存储局部变量的地址——同一个局部变量。这不是你想要的;您想要存储您在 pset_data
中保存的值,而不是存储该值的地址。
快速解决方法是从 data
:
中减掉一颗星
short **data[line_count];
然后将分配更改为:
data[file_index] = pset_data;
这应该是此代码中所需的全部内容。使用data
的代码需要相应的调整。
仔细想想,data
是二维数据集的数组;只需要数据的两颗星和数组的下标。考虑结构类型的数组可能是明智的,其中结构类型封装了一个数据集——它会包含一个指向数据本身的指针,也可能包含大小信息,也许它会存储文件它来自或关于数据集的其他元数据。这将避免多星问题。当您拥有三颗星时,很难跟踪正在发生的事情。如果你真的有 N 维数据,那么你可能需要在声明中添加 N 个星号,但辅助数据结构也变得越来越 rococo。但要避免三颗星指针。正如评论中所指出的, Three-Star Programmer 不是一个免费的绰号。偶尔——非常偶尔——有必要。这通常不是必需的,应尽可能避免。
我正在尝试从 HDF5 文件中预加载一堆矩阵并将它们存储在一个动态数组中。但是,我无法让它像我希望的那样工作。 由于某种我无法弄清楚的原因,整个数组被覆盖而不是子数组。有什么解决办法吗?
这是我的代码:
short ***data[line_count];
short** dset_data;
for (int file_index = 0; file_index < line_count; ++file_index){
dset_data = (short**) malloc(DIM_Y * sizeof(short*));
dset_data[0] = (short*) malloc(DIM_Y * DIM_X * sizeof(short));
for (int i=1; i < DIM_Y; i++)
dset_data[i] = dset_data[0] + i * DIM_X;
for (int y = 0; y < DIM_Y; y++) {
for (int x = 0; x < DIM_X; x++) {
dset_data[y][x] = 0;
}
}
/* Open an existing file. */
file_id = H5Fopen(input_files[file_index], H5F_ACC_RDONLY, H5P_DEFAULT);
/* Open an existing dataset. */
dataset_id = H5Dopen2(file_id, "data/data", H5P_DEFAULT);
/* Read dataset */
status = H5Dread(dataset_id, H5T_NATIVE_SHORT, H5S_ALL, H5S_ALL, H5P_DEFAULT, &dset_data[0][0]);
/* Store two dimensional array at n-th position in data array */
data[file_index] = &dset_data;
/* Close the dataset. */
status = H5Dclose(dataset_id);
/* Close the file. */
status = H5Fclose(file_id);
}
将评论减去对三星级数据的下意识反应,转化为答案。
data
的声明:
short ***data[line_count];
和分配给它的行:
data[file_index] = &pset_data;
是麻烦的根源。您在每次迭代中存储局部变量的地址——同一个局部变量。这不是你想要的;您想要存储您在 pset_data
中保存的值,而不是存储该值的地址。
快速解决方法是从 data
:
short **data[line_count];
然后将分配更改为:
data[file_index] = pset_data;
这应该是此代码中所需的全部内容。使用data
的代码需要相应的调整。
仔细想想,data
是二维数据集的数组;只需要数据的两颗星和数组的下标。考虑结构类型的数组可能是明智的,其中结构类型封装了一个数据集——它会包含一个指向数据本身的指针,也可能包含大小信息,也许它会存储文件它来自或关于数据集的其他元数据。这将避免多星问题。当您拥有三颗星时,很难跟踪正在发生的事情。如果你真的有 N 维数据,那么你可能需要在声明中添加 N 个星号,但辅助数据结构也变得越来越 rococo。但要避免三颗星指针。正如评论中所指出的, Three-Star Programmer 不是一个免费的绰号。偶尔——非常偶尔——有必要。这通常不是必需的,应尽可能避免。