通用堆栈库的问题

时间:2014-02-27 10:45:34

标签: c pointers stack void

我正在尝试编写一个通用堆栈库[使用数组],它可以为任何元素大小和元素数量分配堆栈。我正在尝试下面的代码。 首先,我得到一个警告,说我在memcpy中使用时会取消引用void指针。

其次是我在输出中遇到一些问题,我正在尝试打印。请帮忙。

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

typedef struct _stk_
{
    int top;
    int elemsize;
    int numElem;
    void *array;
}stack;

stack *create_stack(int elemsize, int numElem)
{
    stack *stk_handle = malloc(sizeof(stack));

    if(!stk_handle)
    {
        printf("Malloc failed for stack handle\r\n");
        return NULL;
    }
    stk_handle->top = -1;
    stk_handle->elemsize = elemsize;
    stk_handle->numElem = numElem;
    stk_handle->array = calloc(elemsize, numElem);

    if(!(stk_handle->array))
    {
        printf("Malloc failed for stack\r\n");
        free(stk_handle);
        return NULL;
    }

    return stk_handle;
}

void push (stack *stk_handle, void *element)
{
    memcpy(&(stk_handle->array[++stk_handle->top]), element, stk_handle->elemsize);
    printf("Pushed element %s to stack. Top is %d\r\n", element, stk_handle->top);
}

void pop (stack *stk_handle, void *element)
{
    memcpy(element, &(stk_handle->array[stk_handle->top--]), stk_handle->elemsize);
    printf("Popped element %s from stack. Top is %d\r\n", element, stk_handle->top);
}

int main()
{
    stack *stk_handle = NULL;
    char string1[] = "close";
    char string2[] = "the";
    char string3[] = "door";
    char string4[6], string5[6],string6[6];

    stk_handle = create_stack(6, 5);
    push(stk_handle, &(string1));
    push(stk_handle, &(string2));
    push(stk_handle, &(string3));
    pop(stk_handle, string4);
    pop(stk_handle, string5);
    pop(stk_handle, string6);
    return 1;
}

当我编译时,我得到以下编译警告。

$ gcc stack_lib.c
stack_lib.c: In function âpushâ:
stack_lib.c:39: warning: dereferencing âvoid *â pointer
stack_lib.c: In function âpopâ:
stack_lib.c:45: warning: dereferencing âvoid *â pointer

当我运行程序时,我得到以下输出:

Pushed element close to stack. Top is 0
Pushed element the to stack. Top is 1
Pushed element door to stack. Top is 2
Popped element door from stack. Top is 1
Popped element tdoor from stack. Top is 0
Popped element ctdoortdoor from stack. Top is -1

请让我知道我哪里出错。

2 个答案:

答案 0 :(得分:1)

stk_handle->array[...]取消引用void pointer。由于array成员是void指针,因此您无法直接取消引用它(使用解除引用运算符*或使用类似于您的数组语法)而无需转换为具体类型

请记住,对于数组索引,编译器使用索引乘以基类型来获取正确条目的偏移量。当你有void*什么是基本类型? void本身不是有效的基类型,那么编译器应该将索引乘以?它根本行不通。

我的建议是改为使用int8_t指针,然后将top乘以元素大小:

typedef struct _stk_
{
    int top;
    int elemsize;
    int numElem;
    int8_t *array;
}stack;

...

memcpy(stk_handle->array + (++stk_handle->top * stk_handle->elmsize), ...);

答案 1 :(得分:0)

  1. 可以使用正确的指针算法修复dereferencing void * pointer个警告:

    void push (stack *stk_handle, void *element)
    {
            memcpy((char *)stk_handle->array + ++stk_handle->top * stk_handle->elemsize, element, stk_handle->elemsize);
            printf("Pushed element %s to stack. Top is %d\r\n", (char *)element, stk_handle->top);
    }
    
    void pop (stack *stk_handle, void *element)
    {
            memcpy(element, (char *)stk_handle->array + stk_handle->top-- * stk_handle->elemsize, stk_handle->elemsize);
            printf("Popped element %s from stack. Top is %d\r\n", (char *)element, stk_handle->top);
    }
    

    如果您使用gcc,则不需要在stk_handle之前进行类型转换,请参阅Pointer arithmetic for void pointer in C

  2. &中的push(stk_handle, &(string1));操作是不必要的,你可以写一下

    push(stk_handle, string1);
    push(stk_handle, string2);
    push(stk_handle, string3);