我需要在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];
}
}
你能看到错误在哪里吗?
感谢
你的代码对我来说太复杂了
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
相同。将它封装在一个例程中,这样就不需要两次编写相同的代码。
编辑
对于连续阵列,do:
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];
}
我需要MPI代码的3d连续数组,在进程之间交换2d数组。为此,我使用MPI_Sandrecv例程,它需要连续的数组。
@基思,你的解决方案似乎不起作用。
例如,在这个代码的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的等价物是什么?
我差不多一年前刚开始学习C,而你对这家伙一点帮助都没有。
我还想使用连续的内存块来制作张量,这是一种奇怪的多维对象。想象三个3x3矩阵打印在立方体的三个正交面上。
C中的一个大问题是,当你制作一个3D数组时,arr[number][column][row],这将是"列x行"矩阵的"数量",内存块是连续的,但它没有很好的顺序。
你有没有想过为什么要初始化一个数组,比如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似乎用随机垃圾数据填充垃圾数据槽,它们并不都是"\0"或类似的东西。
所以我想使用指针来修改矩阵的大小,因此我必须为基于指针的操作创建同构。
现在,当我声明一个指针并将其指向矩阵的第一个条目时:
ptr=&a[0][0][0];
然后我打印
L_ptr_print(ptr,(2*4*4));
这将吐出正确的矩阵条目,在这种情况下是两个4x4矩阵。
但我们都知道数组从零开始计数,所以数组arr[2][4][4]实际上有3*5*5个sizeof(int)大的"槽"。所以,让我们打印插槽!
L_ptr_print(ptr,(3*5*5));
您将得到的是前32个条目是正确排序的矩阵条目。接下来的43个条目是当您完全打印出矩阵arr[2][4][4]时得到的垃圾数据。
因此,我已经确定,制作3D动态分配的连续阵列的最简单、最优雅的方法不是首先将其制作成3D。
只需对指针进行malloc处理,大小就等于数组元素的数量。因此,您需要malloc一个32*sizeof(int)指针:
int* ptr;
ptr=(int*)malloc(32*sizeof(int));
然后像这样填充数组的每个元素,或者按照你想做的方式填充。
for(i=0;i<31;i++)
{
*(ptr+i)=i+1;
}
这可以打印32个int,并且它只有32*sizeof(int)字节。这消除了对双指针和三指针的需要。
或者,如果你已经有了一个矩阵,你总是可以手动将单个指针指向每个块,然后你不必担心清除内存,因为你的指针不会占用内存,数组会占用内存,指针指向数组。但是,您不能在运行时修改数组的大小。