Функция стека и толчка () - PullRequest
       6

Функция стека и толчка ()

0 голосов
/ 18 января 2019

Я делаю упражнение и хочу получить поддержку. Проблема заключается в следующем: у меня есть две структуры (1 для узлов стека, 1 для стека). В структуре узла есть поле данных void *.

Я пытался поместить значение в стек, но из-за пустых данных вместо простых данных мне не удалось.

Это код о структурах и функции push ().

struct upo_stack_node_s
{
    void *data;
    struct upo_stack_node_s *next; 
};
typedef struct upo_stack_node_s upo_stack_node_t;

struct upo_stack_s
{
    upo_stack_node_t *top;
    size_t size;
};

/*Function for create the stack*/
upo_stack_t upo_stack_create()
{
    upo_stack_t stack = malloc(sizeof(struct upo_stack_s));
    if (stack == NULL)
    {
        fprintf(stderr, "Unable to create a stack!\n");
        abort();
    }

    stack->top = NULL;
    stack->size = 0;

    return stack;
}

/*Push() function:*/
void upo_stack_push(upo_stack_t stack, void *data)
{
    /* TO STUDENTS:
    *  Remove the following two lines and put here your implementation
    */     
    upo_stack_node_t *node = malloc(sizeof(struct upo_stack_node_s));
    node->data = data; /*<-- Here's the problem */
    node->next = stack->top;
    stack->top = node;
    ++stack->size;
}

/*Top() function*/
void* upo_stack_top(const upo_stack_t stack)
{
    /* TO STUDENTS:
     *  Remove the following two lines and put here your implementation
     */
    return (void *)(stack->top); //<---
}

/*Function for testing (there are other functions in the code)*/
void test_top()
{
    int value1 = 1;
    int value2 = 2;
    upo_stack_t stack;

    stack = upo_stack_create();

    upo_stack_push(stack, &value1); //<----
    upo_stack_push(stack, &value2); //<----

    assert( upo_stack_top(stack) != NULL );
    assert( *((int*) upo_stack_top(stack)) == value2 ); <-- Here's the error

    upo_stack_pop(stack, 0);

    assert( upo_stack_top(stack) != NULL );
    assert( *((int*) upo_stack_top(stack)) == value1 );

    upo_stack_pop(stack, 0);

    assert( upo_stack_top(stack) == NULL );

    upo_stack_destroy(stack, 0);
}

1 Ответ

0 голосов
/ 18 января 2019

Вы всегда должны передавать указатель void. Это означает, что если вы хотите передать простое значение, такое как 1, вам нужно выделить целочисленное значение и передать на него указатель (как пустой указатель).

Таким образом, что-то вроде:

int x = 4;
upo_stack_push(upo_stack, &x);

Конечно, вы должны убедиться, что переменная int x не выходит из области видимости, иначе указатель укажет на свободную память, что приведет к неприятным проблемам с памятью.

Обновление

Предполагается, что указатель void, который вы передаете, уже хранится в памяти для области видимости стека. В случае, если вы хотите, чтобы сам стек копировал данные, вы также должны использовать для этого пространство malloc, таким образом не только неправильно блокируя узел, но также блокируя и копируя передаваемый тип данных. Также, чтобы узнать размер данных (поскольку это пустой указатель, который не знает о его типе), вы должны добавить параметр размера int в функцию push.

Чтобы сохранить целочисленное значение, передайте его как указатель с size: sizeof (int). Чем для копирования структуры данных, используйте memcpy. Это работает только для простых типов и структур без указателей. Если вам нужно копировать структуры с помощью указателей (таким образом, вам нужно так называемое глубокое копирование), то это сложнее.

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