我的结构定义为:
struct Voxel1
{
float array[16];
};
以后我可以将图像分配为指定数量数量体素的连续内存,例如,
int voxelNum = 1000;
Voxel1* image = (Voxel1*)calloc(voxelNum, sizeof(Voxel1));
然后,我可以访问sizeof(Voxel1)
的连续内存进行一些操作,例如,
Voxel1 a;
//do some computation on a,
//copy it to the 101-th voxel in the image
image[100] = a;
我的问题是,稍后我决定在运行时确定数组的大小,即Voxel1中的数组成员具有动态大小。有什么方法可以做到吗?我的要求是,我不想保存其他成员来指示数组的大小,如下所示:
struct Voxel2
{
size_t size;
float* array;
}IDontWantThisDefinition;
由于此额外的成员,后来我的实际voxel2大小将是sizeof(float)*size+sizeof(size_t)
,现在我尝试修改体素值时,它们不像以前那样连续。
我想要的是一些定义(我知道voxel3是无效的)具有以下定义,除了可以在运行时确定size
:
struct Voxel3
{
//so I want size to be static so that it does not take memory on the stack
//also I want it to be const so that it can be used to define array's size
static const size_t size;
float array[size];
}DesireButInvalidDefinition;
在程序中,我可以做这样的事情:
int main(int argc, char** argv)
{
int arraysize = 32;
//allocate 1000 voxels where each voxel has 32 float element
Voxel3* image = (Voxel3*)calloc(1000, sizeof(Voxel3));
Voxel3 anotherVoxel;
image[100]=anotherVoxel;
}
我不确定是否有任何解决方案可以满足这种设计,或者设计可以做一些与我想要的事情。预先感谢。
很难说是什么是最好的方法,但是正如我在最高评论中提到的那样,将大小移动结构定义。
首先,您必须在执行任何操作之前计算动态大小。
int voxel_size; // dynamically computed
typedef struct _Voxel {
float *array; // count is voxel_size
} Voxel;
typedef struct _VoxelArray {
int count;
Voxel *voxels;
} VoxelArray;
void
voxel_init(Voxel *vox)
{
vox->array = calloc(voxel_size,sizeof(float));
}
Voxel *
voxel_alloc(int count)
{
Voxel *vox;
vox = calloc(count,sizeof(voxel));
for (int idx = 0; idx < count; ++idx)
voxel_init(vox + idx);
return vox;
}
VoxelArray *
voxel_array(VoxelArray *arr,int count)
{
if (arr == NULL)
arr = calloc(1,sizeof(VoxelArray));
arr->count = count;
arr->voxels = voxel_alloc(count);
return arr;
}
int
main(int argc, char** argv)
{
voxel_size = 32;
Voxel anotherVoxel;
voxel_init(&anotherVoxel);
//allocate 1000 voxels where each voxel has 32 float element
Voxel *image = voxel_alloc(1000);
image[100] = anotherVoxel;
VoxelArray varray;
voxel_array(&varray,1000);
varray.voxels[100] = anotherVoxel;
VoxelArray *varrptr = voxel_array(NULL,1000);
varrptr->voxels[100] = anotherVoxel;
return 0;
}
通过分开数据和数据访问者,这就是我得到的。不过,这不是内存管理的一个很好的例子。
#include <cstddef>
#include <cstdlib>
// Both Voxel3 and Voxel3Image are just data accessors,
// which provide a way to access the real data.
struct Voxel3
{
static size_t size;
float *array;
Voxel3(float *data = nullptr) {
array = data;
}
// 'image[100]=anotherVoxel;' won't do the right
// thing(deep copy) without this.
Voxel3 & operator = (const Voxel3 &v) {
for (size_t i = 0; i < size; ++i)
array[i] = v.array[i];
return *this;
}
};
size_t Voxel3::size;
// you want image[100], use this.
struct Voxel3Image
{
float *data_ref;
Voxel3Image(float *data = nullptr) {
data_ref = data;
}
// image[100] need this.
Voxel3 operator [] (int i) {
return Voxel3(data_ref + i * Voxel3::size);
}
};
int main(int argc, char** argv)
{
Voxel3::size = 32;
float *real_data = (float*)calloc(1000,
sizeof(float) * Voxel3::size);
// sizeof(Voxel3) == sizeof(float *),
// not what your want.
// allocate 1000 voxels where each voxel has 32 float element
Voxel3Image image( real_data );
Voxel3 anotherVoxel;
// initialize anotherVoxel
image[100]=anotherVoxel;
return 0;
}