Выделите память на символ *** в C
Итак, у меня проблемы с выделением памяти для char ***
переменная типа Моя цель состоит в том, чтобы создать матрицу строк, и код, который у меня сейчас есть для выделения памяти, выглядит следующим образом:
char ***matrix;
matrix = calloc(n*MAX_STR, sizeof(char**));
for(z = 0; z < n; z++) {
matrix[z] = calloc(n, sizeof(char*));
for(i = 0; i < MAX_STR; i++) {
matrix[z][i] = calloc(MAX_STR, sizeof(char));
}
}
Я успешно выделил память для массива строк, используя это:
char **list;
list = calloc(n, sizeof(char *));
for (j = 0; j < n; j++){
list[j] = calloc(MAX_STR, sizeof(char));
}
но сейчас у меня проблемы с матрицей.
Запуск программы с параметром --leak-check=full в Valgrind дает мне следующее сообщение:
==5126== Invalid write of size 8
==5126== at 0x400B9F: createmat (proj.c:100)
==5126== by 0x401598: main (proj.c:237)
==5126== Address 0x5210878 is 0 bytes after a block of size 72 alloc'd
==5126== at 0x4C2ABB4: calloc (vg_replace_malloc.c:593)
==5126== by 0x400B52: createmat (proj.c:98)
==5126== by 0x401598: main (proj.c:237)
Я хотел бы выяснить, как выделить память для этого, так как я все еще начинающий, когда дело доходит до управления памятью в C. Любая помощь будет оценена, спасибо.
РЕДАКТИРОВАТЬ: Матрица должна хранить n массивов строк, которые соответствуют строкам ввода (это читается с fgets
позже), и каждый массив выделяет любое количество слов в строке, причем каждое слово (чтение, каждая строка) имеет максимум MAX_STR
количество символов.n
переменная, читаемая из ввода, в то время как MAX_STR
константа, определенная в программе.
3 ответа
Предполагая, что вы хотите выделить хранилище для n
массивы, каждый с n
строки, каждая до MAX_STR
долго, есть пара ошибок в коде
matrix = calloc(n*MAX_STR, sizeof(char**));
должно быть
matrix = calloc(n, sizeof(char**));
а также
for(i = 0; i < MAX_STR; i++) {
должно быть
for(i = 0; i < n; i++) {
Чуть более подробно,
matrix = calloc(n*MAX_STR, sizeof(char**));
for(z = 0; z < n; z++) {
кажется неправильно. Вы выделяете n*MAX_STR
элементы, но только использовать n
из них
matrix[z] = calloc(n, sizeof(char*));
for(i = 0; i < MAX_STR; i++) {
также сомнительно и неправильно для n<MAX_STR
, (Вы выделяете n
элементы затем пишут MAX_STR
из них.)
Наконец, в зависимости от того, считаете ли вы MAX_STR
чтобы включить место для нулевого терминатора, вам может потребоваться изменить
matrix[z][i] = calloc(MAX_STR, sizeof(char));
в
matrix[z][i] = calloc(MAX_STR+1, 1);
Матрица строк или массив трехмерных символов:
Предположим, вам нужно N
матрицы, каждая матрица может хранить R
строки длины MAX_STR-1
тогда вы должны выделить память вашего цикла следующим образом:
char ***matrix;
matrix = calloc(N, sizeof(char**));
for(z = 0; z < N; z++) {
matrix[z] = calloc(R, sizeof(char*));
for(i = 0; i < R; i++) {
matrix[z][i] = calloc(MAX_STR, sizeof(char));
}
}
Его создаст матрицу как:
matrix
+-------------------+------------------+-----------------------+
| 0 | 1 | 2 |
+-------------------+------------------+-----------------------+
| | |
▼ ▼ ▼
+--+ +----------+ +--+ +----------+ +--+ +----------+
|0 +---►| MAX_STR | |0 +---►| MAX_STR | |0 +---►| MAX_STR |
+--+ +----------+ +--+ +----------+ +--+ +----------+
|1 +---►| MAX_STR | |1 +---►| MAX_STR | |1 +---►| MAX_STR |
+--+ +----------+ +--+ +----------+ +--+ +----------+
|2 +---►| MAX_STR | |2 +---►| MAX_STR |* |2 +---►| MAX_STR |
+--+ +----------+ +--+ +----------+ +--+ +----------+
|3 +---►| MAX_STR | |3 +---►| MAX_STR | |3 +---►| MAX_STR |
+--+ +----------+ +--+ +----------+ +--+ +----------+
|4 +---►| MAX_STR | |4 +---►| MAX_STR | |4 +---►| MAX_STR |
+--+ +----------+ +--+ +----------+ +--+ +----------+
|5 +---►| MAX_STR | |5 +---►| MAX_STR | |5 +---►| MAX_STR |
+--+ +----------+ +--+ +----------+ +--+ +----------+
|6 +---►| MAX_STR | |6 +---►| MAX_STR | |6 +---►| MAX_STR |
+--+ +----------+ +--+ +----------+ +--+ +----------+
|7 +---►| MAX_STR | |7 +---►| MAX_STR | |7 +---►| MAX_STR |
+--+ +----------+ +--+ +----------+ +--+ +----------+
^ ^
| |
| matrix[z][i]
matrix[z]
Здесь N = 3, а
R = 8
Его трехмерный массив размеров matrix[N][R][MAX_STR]
Предположим, если кто-то хочет напечатать строку, которую я пометил *
на диаграмме это третья строка во втором массиве, тогда он / она должен индексировать как
printf("%s",matrix[1][2]);
Несмотря на то, что ответ принят, я обновляю свой ответ, поэтому в будущем он может оказаться полезным
Как вы сказали, вы смогли успешно создать массив строк, используя код ниже:
char **list;
list = calloc(n, sizeof(char *));
for (j = 0; j < n; j++){
list[j] = calloc(MAX_STR, sizeof(char));
}
Теперь вам нужен массив массивов строк, поэтому он должен быть:
char ***matrix;
matrix = calloc(n, sizeof(char**)); //This creates space for storing the address of 'n' array of strings
for(z = 0; z < n; z++) { //This loop creates the 'n' array of strings.
matrix[z] = calloc(n, sizeof(char*));
for(i = 0; i < n; i++) {
matrix[z][i] = calloc(MAX_STR, sizeof(char));
}
}
Итак, в основном, во втором коде вы просто создаете пространство для хранения 'n' списков. Надеюсь, это проясняет.