Присвойте память трехмерному массиву, используя тройной указатель
10129 просмотра
5 ответа
Я должен назначить память для трехмерного массива, используя тройной указатель.
#include <stdio.h>
int main()
{
int m=10,n=20,p=30;
char ***z;
z = (char***) malloc(sizeof(char**)*m*n*p);
return 0;
}
Это правильный способ сделать это? (Я думаю, что я делаю неправильно).
Автор: Rog Matthews Источник Размещён: 12.11.2019 09:46Ответы (5)
6 плюса
Чтобы полностью выделить трехмерный динамический массив, вам нужно сделать что-то вроде следующего:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m=10,n=20,p=30;
char ***z;
z = malloc(m * sizeof(char **));
assert(z != NULL);
for (i = 0; i < m; ++i)
{
z[i] = malloc(n * sizeof(char *));
assert(z[i] != NULL);
for (j = 0; j < n; ++j)
{
z[i][j] = malloc(p);
assert(z[i][j] != NULL);
}
}
return 0;
}
Освобождение данных оставлено в качестве упражнения для читателя.
Автор: Paul R Размещён: 28.05.2012 09:034 плюса
Нет необходимости приводить возвращаемое значение malloc()
в C.
И если вы планируете хранить m * n * p
символы напрямую (и самостоятельно вычислять адрес), то вам, конечно, не следует масштабировать распределение по размеру a char **
.
Ты имеешь в виду:
int m = 10, n = 20, p = 30;
char *z = malloc(m * n * p * sizeof *z);
Это выделит 10 * 20 * 30 = 6000 байтов. Это можно рассматривать как формирование куба высоты p
, где каждый «срез» вдоль вертикальной оси является n * m
байтом.
Так как это для ручной адресации, вы не можете использовать, например, z[k][j][i]
для индексации, вместо этого вы должны использовать z[k * n * m + j * m + i]
.
2 плюса
Если вам не нужно выделять память в одном смежном блоке (который обычно используется в IME), вы должны сделать что-то вроде этого:
char ***z;
z = malloc(sizeof *z * m); // allocate m elements of char **
if (z)
{
int i;
for (i = 0; i < m; i++)
{
z[i] = malloc(sizeof *z[i] * n); // for each z[i],
if (z[i]) // allocate n elements char *
{
int j;
for (j = 0; j < n;j++)
{
z[i][j] = malloc(sizeof *z[i][j] * p); // for each z[i][j],
if (z[i][j]) // allocate p elements of char
{
// initialize each of z[i][j][k]
}
}
}
}
}
Обратите внимание, что вам нужно освободить эту память в обратном порядке:
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
free(z[i][j];
free(z[i]);
}
free(z);
Если вам действительно нужно, чтобы память была распределена в непрерывном фрагменте, у вас есть несколько вариантов. Вы можете выделить один блок и вычислить свои смещения вручную:
char *z = malloc(sizeof *z * m * n * p); // note type of z!
...
z[i * m + j * n + k] = some_value();
Когда вы закончите, вам просто нужно сделать один free
:
free(z);
Если у вас есть компилятор C99 или компилятор C11, который поддерживает массивы переменной длины, вы можете сделать что-то вроде этого:
int m=..., n=..., p=...;
char (*z)[n][p] = malloc(sizeof *z * m);
Это объявляется z
как указатель на массив n
x , и мы выделяем такие элементы. Память распределяется непрерывно, и вы можете использовать обычный синтаксис индексации трехмерного массива ( ). Как и в предыдущем методе, вам нужен только один вызов:p
char
m
z[i][j][k]
free
free(z);
Если вы не имеете C99 компилятора или C11 компилятора , который поддерживает Влас, вам нужно будет сделать n
, и p
время компиляции константа, такими как
#define n 20
#define p 30
в противном случае последний метод не сработает.
редактировать
m
не нужно быть константой времени компиляции в этом случае, просто n
и p
.
0 плюса
Вам понадобится следующий вложенный цикл -
z = (char**)malloc(sizeof(char*) * m);
for (int i = 0; i < m; ++i)
{
*(z + i) = (char*)malloc(sizeof(char*) * n);
for (int j = 0; j < n; ++j)
{
*(*(z + i)) = (char)malloc(p);
}
}
Может быть не синактически точным, но это должно быть что-то в этом роде.
Автор: Superman Размещён: 28.05.2012 09:040 плюса
Вы sizeof(char)
не хотите, так sizeof(char**)
как последний даст вам размер указателя, который в большинстве современных систем будет 4 байта вместо ожидаемого 1.
Вопросы из категории :
- c Как вы форматируете unsigned long long int, используя printf?
- c What are the barriers to understanding pointers and what can be done to overcome them?
- c Как реализовать продолжения?
- c Как вы передаете функцию в качестве параметра в C?
- c Как получить список каталогов в C?
- pointers Regular cast vs. static_cast vs. dynamic_cast
- pointers Каковы различия между переменной-указателем и ссылочной переменной в C ++?
- pointers Почему я не могу конвертировать 'char **' в 'const char * const *' в C?
- memory-management Setting Objects to Null/Nothing after use in .NET
- memory-management Как работает пул автозапуска NSAutoreleasePool?
- memory-management Что и где находится стек и куча?
- memory-management Как имитировать ошибки выделения памяти
- memory-management Что такого плохого в использовании GC.Collect ()?
- multidimensional-array Как вы вращаете двумерный массив?
- multidimensional-array Проверка, является ли массив многомерным или нет?
- multidimensional-array Как «сгладить» многомерный массив в простой в PHP?
- multidimensional-array Каковы различия между многомерным массивом и массивом массивов в C #?
- multidimensional-array Преобразование 2-мерного массива