Указатели на структурную реализацию стековой структуры данных в C - PullRequest
0 голосов
/ 28 апреля 2019

Я создал структуру стека в C. Когда стек инициализируется значением, я могу напечатать его обратно и получить правильный вывод. Однако после нажатия новой строки функция печати печатает случайный символ (ASCII 177).

Первоначально я реализовал этот проект с помощью указателей, но мне не удалось заставить его работать. Вместо этого я решил использовать указатель только для Node *nodes члена Stack. Таким образом, когда мне нужно увеличить стек, я могу просто умножить объем требуемой памяти на Stack.size. Однако этот подход также пока не работает.

#define MAX_DATA 64
struct Node{
    char val[MAX_DATA];
};

struct Stack{
    int size;
    struct Node *nodes;
};

Они используются следующим образом:

struct Node node = {.val = "Test"};
struct Stack stack = newStack(node);
printStack(stack);

Функция newStack правильно инициализирует nodes. Ради включения:

struct Stack newStack(struct Node node)
{
    struct Stack stack;
    stack.size = 1;
    stack.nodes = (struct Node*) malloc(sizeof(struct Node));
    stack.nodes[0] = node;
    return stack;
}

Затем стек печатается итеративно в printStack(), где stack.size является верхней границей цикла for.

Проблема возникает, когда я пытаюсь запустить:

struct Node node2 = {.val = "Test1"};
push(stack, node2);
printStack(stack);

Функция push предназначена для создания временного стека и присвоения ему значения стека. После этого значение size увеличивается, указатель на nodes освобождается и выделяется новая память с местом для нового члена в конце.

void push(struct Stack stack, struct Node node)
{
    struct Stack temp_stack = stack;
    stack.size += 1;
    free(stack.nodes);
    stack.nodes = (struct Node*) malloc(sizeof(struct Node) * stack.size);
    for(int i = 0; i < temp_stack.size; i++){
        stack.nodes[i] = temp_stack.nodes[i];
    }
    stack.nodes[stack.size - 1] = node;
}

Излишне говорить, что это не выполняется должным образом.

Ожидаемый результат будет:

Test
Test1

Но вместо этого я получаю только ASCII-177. Также стоит отметить, что выполнение зависает после того, как оно напечатает это и переместится на новую строку. Это приводит к Aborted (core dumped).

Неправильно ли я освобождаю и перераспределяю память? Любая помощь будет оценена. Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 28 апреля 2019

Спасибо peekay за рекомендации.Я закончил переписывать.Это стало немного проще.Я удалил слой «видимости», сохранив узлы в качестве указателя, но я полагаю, что эта реализация немного более верна структуре данных.

Узел реализован как средство для хранения данных, ипользователь не взаимодействует с ним напрямую.Это также указывает на следующий узел.Стек реализован для хранения верхнего узла, а также размера стека.

Узел:

struct Node{
    char val[MAX_DATA];
    struct Node *next;
};

Стек:

struct Stack{
    struct Node *top;
    int size;
};

Толчок:

void push(struct Stack *stack, char *newVal)
{
    struct Node *newNode;
    newNode = (struct Node*) malloc(sizeof(struct Node));
    strcpy(newNode->val, newVal);
    newNode->next = stack->top;
    stack->top = newNode;
    stack->size++;
}

Использование:

struct Stack stack;
newStack(&stack);

push(&stack, "Test");
push(&stack, "Test1");
push(&stack, "Test2");
push(&stack, "Test3");

Полный код

Обновлены доступные узлы

0 голосов
/ 28 апреля 2019

Стоит помнить, что в C передача структуры функции является передачей по значению , т. Е. Функция получает копию структуры.Все члены структуры, включая переменные-указатели (но не те, на которые ссылается указатель), дублируются.

Итак, в функции push подумайте о том, что происходит с оригиналом при изменении этой копии (например, * 1007).*, а также когда вы free() стековые узлы.

...