我需要在C中构建两个3D连续数组(标记为x0
和x
)。尺寸必须为x[size_tot_y][size_tot_x][size_tot_z]
和x0[size_tot_y][size_tot_x][size_tot_z]
。这是我的代码:
double*** x;
double** x_val2;
double*** x0;
double** x0_val2;
x0 = malloc(size_tot_y*sizeof(double**));
x0_val2 = malloc(size_tot_x*size_tot_y*size_tot_z*sizeof(double*));
x = malloc(size_tot_y*sizeof(double**));
x_val2 = malloc(size_tot_x*size_tot_y*size_tot_z*sizeof(double*));
for(j=0;j<=size_tot_y-1;j++) {
x0[j] = &x0_val2[j*size_tot_x*size_tot_z];
x[j] = &x_val2[j*size_tot_x*size_tot_z];
}
for(i=0;i<=size_tot_y-1;i++) {
for(j=0;j<=size_tot_x-1;j++) {
x0[i][j] = malloc(size_tot_z*sizeof(double));
x[i][j] = malloc(size_tot_z*sizeof(double));
}
}
for(i=0;i<=size_tot_y-1;i++) {
for(j=0;j<=size_tot_x-1;j++) {
x0[i][j] = x0_val2[i*j*size_tot_z];
x[i][j] = x_val2[i*j*size_tot_z];
}
}
你能看到错误在哪里吗?
由于
答案 0 :(得分:1)
你的代码对我来说似乎太复杂了。只是做:
double ***x;
x = malloc(size_tot_y * sizeof(*x));
for (i = 0; i < size_tot_y; i++) {
x[i] = malloc(size_tot_x * sizeof(**x));
for (j = 0; j < size_tot_x; j++) {
x[i][j] = malloc(size_tot_z * sizeof(***x));
}
}
x0
相同。将其包装在例程中,这样您就不需要两次编写相同的代码。
修改强>
对于连续数组,请执行:
double *storage = malloc(size_tot_x * size_tot_y * size_tot_z * sizeof(*storage));
double *alloc = storage;
double ***x;
x = malloc(size_tot_y * sizeof(*x));
for (i = 0; i < size_tot_y; i++) {
x[i] = malloc(size_tot_x * sizeof(**x));
for (j = 0; j < size_tot_x; j++) {
x[i][j] = alloc;
alloc += size_tot_z;
}
}
如果你真的想要指针的话。如果没有,只需分配所有内存并自行编制索引:
double *storage = malloc(size_tot_x * size_tot_y * size_tot_z * sizeof(*storage));
double get(const double *storage, int x, int y, int z) {
return storage[(y * size_tot_x + x) * size_tot_z + z];
}
答案 1 :(得分:0)
我需要用于MPI代码的3d连续数组,我在进程之间交换2d数组。为此,我使用MPI_Sendrecv例程,这需要连续的数组。
@Keith,您的解决方案似乎无法运作。
例如,在此代码的2D版本中,我以这种方式创建2D连续数组x0
:
x0 = malloc(size_tot_y*sizeof(double*));
x0_vals = malloc(size_tot_x*size_tot_y*sizeof(double));
for(j=0;j<=size_tot_y-1;j++) {
x0[j] = &x0_vals[j*size_tot_x];
}
3D的等价物是什么?
答案 2 :(得分:0)
我差不多一年前刚开始做C而且你一点都不帮这个人。
我还想使用连续的内存块来制作张量,它们是奇怪的多维对象。想想在立方体的3个正面上印刷的三个3x3矩阵。
C中的一个大问题是当你制作一个3D数组时,arr [number] [column] [row],这将是&#34; number&#34; &#34;列x行&#34;矩阵,内存块连续,但它没有很好的排序。
你有没有想过为什么要初始化一组说arr [2] [4] [4]
int arr[2][4][4]=
{
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
},
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
{13, 14, 15, 16}
},
};
但是我们都知道C开始计数为零,所以我们将矩阵嵌入到一个更大的矩阵中,周围有垃圾数据,第三个矩阵完全是垃圾数据。这是我打印垃圾数据的方式:
#define COMPLEX 2
#define ROW 2
#define COLUMN 2
void L_print(int u[COMPLEX][ROW][COLUMN])
{
int i,j,k;
for(i=0;i<=COMPLEX;i++)
{
for(j=0;j<=ROW;j++)
{
for(k=0;k<=COLUMN;k++)
{
printf("%d ",u[i][j][k]);
}
printf("\n");
}
printf("\n");
}
}
因此,您可以获得嵌入垃圾矩阵中的正确数据。 C似乎用随机垃圾数据填充垃圾数据槽,它们不是全部&#39; \ 0&#39;或类似的东西。
所以我想使用指针来修改矩阵大小的运行时,因此我必须根据指针对我的操作进行同构。
现在,当我声明一个指针并将其指向矩阵的第一个条目时:
ptr=&a[0][0][0];
然后我打印
L_ptr_print(ptr,(2*4*4));
这会吐出正确的矩阵条目,在这种情况下是两个4x4矩阵。
但是我们都知道数组从零开始计数,所以数组arr [2] [4] [4]实际上有3 * 5 * 5&#34;插槽&#34;这是sizeof(int)big。所以,让我们打印插槽!
L_ptr_print(ptr,(3*5*5));
您将得到的是前32个条目是正确排序的矩阵条目。接下来的43个条目是完全打印矩阵arr [2] [4] [4]时得到的垃圾数据。
因此,我已经确定,制作3D动态分配连续数组的最简单,最优雅的方法并非首先使其成为3D。
简单地指向你的指针并使其大小等于数组元素的数量。所以你要malloc一个32 * sizeof(int)指针:
int* ptr;
ptr=(int*)malloc(32*sizeof(int));
然后像这样填充数组的每个元素,或者你想做什么。
for(i=0;i<31;i++)
{
*(ptr+i)=i+1;
}
这可以打印出32个整数,并且它只有32 * sizeof(int)个字节。这消除了对双指针和三指针的需要。
或者如果你已经有一个矩阵,你总是可以手动指向每个块的单个指针,然后你不必担心清除内存因为你的指针没有占用内存,数组做,指针指向数组。但是,您无法在运行时修改数组的大小。