How can I memcpy a 3d pointer to another 3d? I already tried the following:
void somefunction(ArrayBlock **** b1, int noOfBlocks, ArrayBlock **** b2){
memcpy((&b2), (&b1), noOfBlocks*sizeof(ArrayBlock));
}
This gives me the following error in gdb:
[Inferior 1 (process 8528) exited with code 030000000005]
both b1 and b2 were allocated memory in the main function like this:
ArrayBlock ***b2;
b2 = malloc(max_x * sizeof(ArrayBlock **));
for (i = 0; i < max_x; ++i)
{
b2[i] = malloc(max_y * sizeof(ArrayBlock *));
for (j = 0; j < max_y; ++j)
{
b2[i][j] = malloc(max_z* sizeof(ArrayBlock));
}
}
Solution:
I figured that because the initialization of my 3D pointer (array) was non-contiguous, one memcpy will not be enough.
so this is what I did:
int i2, j2;
for(i2 = 0; i2 < max_x; i2++){
for(j2 = 0; j2 < max_y; j2++){
memcpy(&(*b2)[i2][j2][0], &(*b1)[i2][j2][0], max_z*sizeof(ArrayBlock));
}
}
I think this time it works for real, thanks to those who helped me.
That depends how your 3D array was allocated, but in the most common case (array of arrays of arrays) the answer is no.
There is a way to allocate a 3D array in such way that it's possible, however:
Stuff* pXyz
)Stuff** ppXy
)pXyz
(ppXy[x*CY + y] = &pXyz[x*CY*CZ + y*CZ + 0];
)Stuff*** pppX
)ppXy
(pppX[x] = &ppXy[x*CY + 0];
)return pppX;
I hope I didn't get these wrong, but it's the base idea: One dimension, one malloc.
Stuff*** Alloc3DArray(size_t cx, size_t cy, size_t cz) {
Stuff*** ret = NULL;
/*Allocate a single CX*CY*CZ array of Stuffs*/
Stuff* pXyz = malloc(cx * cy * cz * sizeof(*pXyz));
if(pXyz!=NULL) {
/*Allocate a single CX*CY array of pointers to Stuff*/
Stuff** ppXy = malloc(cx * cy * sizeof(*ppXy));
if(ppXy!=NULL) {
/*Allocate a single CX array of pointers to pointers to Stuff*/
Stuff*** pppX = malloc(cx * sizeof(*pppX));
if(pppX!=NULL) {
/*Initialize ppXy with pointers to various areas of pXyz*/
size_t x, y;
for(x=0 ; x<cx ; x++){
for(y=0 ; y<cy ; y++){
ppXy[x*cy + y] = &pXyz[x*cy*cz + y*cz + 0];
}
}
/*Initialize pppX with pointers to various areas of ppXy*/
for(x=0 ; x<cx ; x++){
pppX[x] = &ppXy[x*cy + 0];
}
/*Success!*/
ret = pppX;
} else {
/*Allocating third level failed: free first and second levels*/
free(ppXy), ppXy=NULL;
free(pXyz), pXyz=NULL;
}
} else {
/*Allocating second level failed: free first level*/
free(pXyz), pXyz=NULL;
}
}
return ret;
}
With this, you can memcpy this:
memcpy(&pppDest[0][0][0], &pppSource[0][0][0], CX*CY*CZ*sizeof(***pppDest));
Added: And when you're done with the array, if you've done it right it can be freed thusly:
void Free3DArray(Stuff ***pppArr) {
if(pppArr != NULL) {
free(**pppArr); /*Free third level*/
free( *pppArr); /*Free second level*/
free( pppArr); /*Free first level*/
}
}