Использование указателей для 4-х мерного куба - PullRequest
0 голосов
/ 02 марта 2019

Я пытаюсь напечатать 4D-куб, используя **** указатели

#include <stdio.h>
#include <stdlib.h>

#define DIM 4

void printCube(char ****cube, int dim) {
    int x, y, z;
    for (z = 0; z < dim; z++) {
        for (y = 0; y < dim; y++) {
            for (x = 0; x < dim; x++) {
                printf("%c ", *cube[z][y][x]);
            }
            printf("\n");
        }
        printf("------------------------------------\n");
    }
}

int main() {
    char ***cube = (char ***)malloc(sizeof(char **) * DIM);
    int x, y, z;
    for (z = 0; z < DIM; z++) {
        cube[z] = (char **)malloc(sizeof(char **) * DIM);
        for (y = 0; y < DIM; y++) {
            cube[z][y] = (char *)malloc(sizeof(char *) * DIM);
            for (x = 0; x < DIM; x++) {
                cube[z][y][x] = ((x + y + z) % 26) + 'A';
            }
        }
    }

    printCube(&cube, DIM);

    for (z = 0; z < DIM; z++) {
        for (y = 0; y < DIM; y++) {
            for (x = 0; x < DIM; x++) {
                free(cube[z][y][x]);
            }
            free(cube[z][y]);
        }
        free(cube[z]);
    }
    free(cube);
    return 0;
}

Я уверен, что ошибка проста, но я пытался выяснить это в течение нескольких часов.

Должно быть просто, что я должен использовать указатель на printf что-то еще (потому что, если я печатаю только символы, оно работает нормально)

printf("%c ", *cube[z][y][x]);

есть ли у кого-нибудь советы для меняКак исправить этот код?

Очень ценю вашу поддержку.

Ответы [ 3 ]

0 голосов
/ 02 марта 2019

В вашем коде есть несколько проблем:

  • Ваш куб имеет только 3 измерения, это обычный куб, представленный в виде массива указателей на массивы указателей на массивы int.Передача этого массива в функцию printCube напрямую передаст указатель на его первый элемент типа int ***.В вашем случае, поскольку выделен массив верхнего уровня, у вас уже есть указатель с типом int ***.Таким образом, прототип функции должен быть void printCube(char ***cube, int dim).Нет причины передавать адрес указателя вместо его значения.
  • При вычислении размеров выделения есть некоторые ошибки: cube[z] = (char **)malloc(sizeof(char **) * DIM); должно быть

    cube[z] = (char **)malloc(sizeof(char *) * DIM);
    

    и cube[z][y] = (char *)malloc(sizeof(char *) * DIM); должно быть

    cube[z][y] = (char *)malloc(sizeof(char) * DIM);
    
  • Вы должны удалить уровень в ваших циклах освобождения, поскольку cube[z][y][x] не является выделенным указателем, а просто символом в массиве, указывающем нана cube[z][y].Жаль, что ваш компилятор принимает этот код с простым предупреждением.Вы должны использовать gcc -Wall -Werror, чтобы избежать таких глупых ошибок.

Вот исправленная версия:

#include <stdio.h>
#include <stdlib.h>

#define DIM 4

void printCube(char ***cube, int dim) {
    int x, y, z;
    for (z = 0; z < dim; z++) {
        for (y = 0; y < dim; y++) {
            for (x = 0; x < dim; x++) {
                printf("%c ", cube[z][y][x]);
            }
            printf("\n");
        }
        printf("------------------------------------\n");
    }
}

int main() {
    char ***cube = (char ***)malloc(sizeof(char **) * DIM);
    int x, y, z;
    for (z = 0; z < DIM; z++) {
        cube[z] = (char **)malloc(sizeof(char *) * DIM);
        for (y = 0; y < DIM; y++) {
            cube[z][y] = (char *)malloc(sizeof(char ) * DIM);
            for (x = 0; x < DIM; x++) {
                cube[z][y][x] = ((x + y + z) % 26) + 'A';
            }
        }
    }

    printCube(cube, DIM);

    for (z = 0; z < DIM; z++) {
        for (y = 0; y < DIM; y++) {
            free(cube[z][y]);
        }
        free(cube[z]);
    }
    free(cube);

    return 0;
}

Вывод:

A B C D
B C D E
C D E F
D E F G
------------------------------------
B C D E
C D E F
D E F G
E F G H
------------------------------------
C D E F
D E F G
E F G H
F G H I
------------------------------------
D E F G
E F G H
F G H I
G H I J
------------------------------------
0 голосов
/ 02 марта 2019

Вы являетесь жертвой операторского приоритета.В С оператор пост-исправления имеет более высокий приоритет, чем оператор пред-исправления.В вашем случае оператор префикса - '*', а оператор пост-исправления - '[]'

Итак, выражение:

*cube[z][y][x]

эквивалентно:

*(cube[z][y][x])

, что нежелательно, поскольку cube[z][y][x] - это указатель, указывающий на недопустимую память, и попытка использовать этот указатель приведет к неопределенному поведению.

Сначала необходимо отменить ссылку на указатель cube изатем используйте нижние операторы:

(*cube)[z][y][x]

Это решит вашу проблему.С другой стороны, поскольку вы не пытаетесь изменить значение указателя cube в функции и просто используете его значение, вы можете упростить свою функцию, чтобы получить char ***.Затем вы передаете указатель cube по значению, и вам не нужно беспокоиться о приоритете оператора.

0 голосов
/ 02 марта 2019

Вам не нужно брать адрес cube при передаче его на printCube.Вместо этого просто передайте его напрямую, объявите его как char *** в printCube, а затем получите доступ к нему как cube[z][y][x] в printCube.

Как сейчас, вы используете *cube[z][y][x]в printCube, который не работает, потому что * связывается более свободно, чем [].Это будет работать, если вы измените его на (*cube)[z][y][x].Но, как я уже сказал, во-первых, нет необходимости в дополнительном уровне косвенности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...