Есть несколько вариантов. Если вам нужно выделить всю структуру памяти одновременно, вы, вероятно, захотите выделить указатель на указатель на массив int[500]
(int (**)[500]
), а не выделять указатель-на-указатель-на-указатель int
(int ***
) - хотя оба они технически верны.
( примечание: Я использовал int
в примере поэтому просто измените тип a
на double
, чтобы удовлетворить ваши потребности)
Чтобы приблизиться к выделению для указатель на указатель на массив int[500]
, начните с вашего указателя и выделите 1500
указателей, например,
#define Z 500
#define X 1500
#define Y X
int main (void) {
int (**a)[Z] = NULL; /* pointer to pointer to array of int[500] */
if (!(a = malloc (X * sizeof *a))) { /* allocate X pointers to (*)[Z] */
perror ("malloc-X (**)[Z]");
return 1;
}
. На данный момент у вас есть 1500 указателей на массив int[500]
. Вы можете l oop каждого указанного выше указателя, выделяя 1500 * sizeof (int[500)
и назначая начальный адрес каждому блоку, выделенному одному из указателей, например,
for (int i = 0; i < X; i++) /* for each pointer */
if (!(a[i] = malloc (Y * sizeof **a))) { /* alloc Y * sizeof int[Z] */
perror ("malloc-YZ (*)[Z]");
return 1;
}
Теперь вы можете адресовать каждое целое число в вашем распределении как a[x][y][z]
. Затем, чтобы освободить выделенную память, вы просто free()
в обратном порядке, например,
for (int i = 0; i < X; i++)
free (a[i]); /* free allocated blocks */
free (a); /* free pointers */
Короткий пример, который выполняет это и записывает значение в каждый индекс, может быть:
#include <stdio.h>
#include <stdlib.h>
#define Z 500
#define X 1500
#define Y X
int main (void) {
int (**a)[Z] = NULL; /* pointer to pointer to array of int[500] */
if (!(a = malloc (X * sizeof *a))) { /* allocate X pointers to (*)[Z] */
perror ("malloc-X (**)[Z]");
return 1;
}
puts ("pointers allocated");
for (int i = 0; i < X; i++) /* for each pointer */
if (!(a[i] = malloc (Y * sizeof **a))) { /* alloc Y * sizeof int[Z] */
perror ("malloc-YZ (*)[Z]");
return 1;
}
puts ("all allocated");
for (int i = 0; i < X; i++) /* set mem to prevent optimize out */
for (int j = 0; j < Y; j++)
for (int k = 0; k < Z; k++)
a[i][j][k] = i * j * k;
puts ("freeing memory");
for (int i = 0; i < X; i++)
free (a[i]); /* free allocated blocks */
free (a); /* free pointers */
}
Пример использования / вывода - запуск по времени
$ time ./bin/malloc_1500x1500x500
pointers allocated
all allocated
freeing memory
real 0m1.481s
user 0m0.649s
sys 0m0.832s
Использование памяти / проверка ошибок
Это 4,5 ГБ выделенной памяти и используется ( предупреждение: вы будете переключаться на 8G или меньше в зависимости от того, что еще у вас работает, если вы запускаете valgrind
)
$ valgrind ./bin/malloc_1500x1500x500
==7750== Memcheck, a memory error detector
==7750== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==7750== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==7750== Command: ./bin/malloc_1500x1500x500
==7750==
pointers allocated
all allocated
freeing memory
==7750==
==7750== HEAP SUMMARY:
==7750== in use at exit: 0 bytes in 0 blocks
==7750== total heap usage: 1,502 allocs, 1,502 frees, 4,500,013,024 bytes allocated
==7750==
==7750== All heap blocks were freed -- no leaks are possible
==7750==
==7750== For counts of detected and suppressed errors, rerun with: -v
==7750== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Посмотрите вещи и дайте мне знать, если у вас вопросы.