Я полагаю, что этот код заставляет выделение памяти для 3-го массива быть непрерывным.
void ***calloc_3d_array(size_t n3, size_t n2, size_t n1, size_t size){
void ***array;
size_t i, j;
if ((array = (void***)calloc(n3, sizeof(void**))) == NULL) {
printf("[calloc_3d] failed to allocate memory for %d 1st-pointers\n",
(int)n3);
return NULL;
}
if ((array[0] = (void**)calloc(n3*n2, sizeof(void*))) == NULL) {
printf("[calloc_3d] failed to allocate memory for %d 2nd-pointers\n",
(int)(n3*n2));
free((void*)array);
return NULL;
}
for (i=1; i<n3; i++) {
array[i] = (void**)((unsigned char*)array[0]+i*n2*sizeof(void*));
}
if ((array[0][0] = (void*)calloc(n3*n2*n1, size)) == NULL) {
printf("[calloc_3d] failed to alloc. memory (%d X %d X %d of size %d)\n",
(int)n3, (int)n2, (int)n1, (int)size);
free((void*)array[0]);
free((void*)array);
return NULL;
}
for (j=1; j<n2; j++) {
array[0][j] = (void**)((unsigned char*)array[0][j-1]+n1*size);
}
for (i = 1; i < n3; i++) {
array[i][0] = (void**)((unsigned char*)array[i-1][0]+n2*n1*size);
for (j = 1; j < n2; j++) {
array[i][j] = (void**)((unsigned char*)array[i][j-1]+n1*size);
}
}
return array;
}
Я пытаюсь преобразовать это в функцию, которая выделяет 4-й массив непрерывно.Я не до конца понимаю 3-й случай безупречно, поэтому абстрагирование до 4-го измерения немного шатко.Я в основном не знаю точно, почему в любом цикле у нас есть либо массив [i] = (void **), либо массив [i] [j] = (void **) в 3-м коде, поэтому в 4-м коде у меня есть весь массив[i] [j] [k] = (недействительно ***).Вот что у меня сейчас есть
void ****calloc_4d_array(size_t n4, size_t n3, size_t n2, size_t n1, size_t size){
void ****array;
size_t i, j, k;
/* Alloc array of 3d pointers */
if ((array = (void****)calloc(n4, sizeof(void***))) == NULL) {
printf("[calloc_3d] failed to allocate memory for %d 1st-pointers\n",
(int)n4);
return NULL;
}
/* In first slot allocate a entire 2d pointer array */
if ((array[0] = (void***)calloc(n4*n3, sizeof(void**))) == NULL) {
printf("[calloc_3d] failed to allocate memory for %d 2nd-pointers\n",
(int)(n4*n3));
free((void*)array);
return NULL;
}
/* Loop over slots and adjust address to accommodate 2d pointers */
for (i = 1; i < n4; i++) {
array[i] = (void***)((unsigned char*)array[0]+i*n3*sizeof(void**));
}
/* In the first 2d pointer, allocate the entire space for 1d pointers*/
if ((array[0][0] = (void**)calloc(n4*n3*n2, sizeof(void*))) == NULL) {
printf("[calloc_3d] failed to allocate memory for %d 3rd-pointers\n",
(int)(n4*n3*n2));
free((void*)array[0]);
free((void*)array);
return NULL;
}
/* Loop over other 2d slots and adjust address to accommodate type */
for (j=1; j<n3; j++) {
array[0][j] = (void**)((unsigned char*)array[0][j-1]+n2*size);
}
for (i=1; i<n4; i++) {
array[i][0] = (void**)((unsigned char*)array[i-1][0]+n3*n2*size);
for (j=1; j<n3; j++) {
array[i][j] = (void**)((unsigned char*)array[i][j-1]+n2*size);
}
}
/* Finally allocate for entire array */
if ((array[0][0][0] = (void*)calloc(n4*n3*n2*n1, size)) == NULL) {
printf("[calloc_3d] failed to alloc. memory (%d X %d X %d X %d of size %d)\n",
(int)n4, (int)n3, (int)n2, (int) n1, (int)size);
free((void*)array[0][0]);
free((void*)array[0]);
free((void*)array);
return NULL;
}
for (k=1; k<n2; k++) {
array[0][0][k] = (void***)((unsigned char*)array[0][0][k-1]+n1*size);
}
for (j=1; j<n3; j++) {
array[0][j][0] = (void***)((unsigned char*)array[0][j-1][0]+n2*n1*size);
for (k=1; k<n2; k++) {
array[0][j][k] = (void***)((unsigned char*)array[0][j][k-1]+n1*size);
}
}
for(i=1; i<n4; i++) {
array[i][0][0] = (void***)((unsigned char*)array[i-1][0][0]+n3*n2*n1*size);
for (j=1; j<n3; j++) {
array[i][j][0] = (void***)((unsigned char*)array[i][j-1][0]+n2*n1*size);
for (k=1; k<n2; k++) {
array[i][j][k] = (void***)((unsigned char*)array[i][j][k-1]+n1*size);
}
}
}
return array;
}
Редактировать : компилятор дал мне предупреждение, касающееся моего (void ***) вопроса, и кажется, что этот массив имеет смысл [][] (void **), но я до сих пор не знаю, почему его устраивает массив [i] = (void ***) вместо массива [i] = (void *).Иначе говоря, почему (void *) с calloc array[0][0][0] = (void*)calloc(n4*n3*n2*n1, size)
, но (void ***) при использовании сдвига бит / установки адреса (?) array[0][0][k] = (void***)((unsigned char*)array[0][0][k-1]+n1*size);
?Я подумал бы, какой бы тип массива объектов [] [] [] не был (void *) или (void ***).