堆栈和push()函数

时间:2019-01-18 11:40:38

标签: c

我正在做运动,并希望获得支持。问题是这样的:我有两个结构(1个用于堆栈的节点,1个用于堆栈)。在节点结构中,有一个void *数据字段。

我试图将值压入堆栈,但是由于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 :(得分:1)

您始终必须传递一个void指针。这意味着如果要传递一个简单的值(如1),您需要做的就是分配一个整数值,然后将指针传递给它(作为空指针)。

因此,类似:

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

当然,您必须确保int变量x不会超出范围,否则指针将指向已释放的内存,这将导致令人讨厌的内存问题。

更新

上面假设,您传递的void指针已经存储在堆栈范围内的内存中。如果您想让堆栈本身复制数据,则还必须为此分配空间,因此不仅要分配节点,还要分配和复制传递的数据类型。同样要知道数据的大小(由于它是一个空指针,不知道其类型),还必须在push函数中添加一个int size参数。

要存储一个整数值,请将其作为指针传递,其大小为:sizeof(int)。比起复制数据结构,请使用memcpy。这仅适用于没有指针的简单类型和结构。如果您必须使用指针来复制结构(因此您需要所谓的深度复制),那将比棘手的多。