Выделите память на символ *** в 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' списков. Надеюсь, это проясняет.

Другие вопросы по тегам