我有一个结构定义为:
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;
由于这个额外的成员,后来我的实际体素2大小将是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;
}
我不确定是否有任何解决方案可以满足这样的设计,或者哪种设计可以做到接近我想要的东西。提前谢谢。
答案 0 :(得分:1)
很难说最好的方法是什么,但正如我在最高评论中提到的那样,将大小移到结构定义之外。
首先,你必须在做任何事情之前计算动态尺寸。
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;
}
答案 1 :(得分:-2)
通过分离数据和数据访问器,这就是我得到的。但不是内存管理的一个很好的例子。
#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;
}