我正在尝试编写一个通用堆栈库[使用数组],它可以为任何元素大小和元素数量分配堆栈。我正在尝试下面的代码。 首先,我得到一个警告,说我在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
请让我知道我哪里出错。
答案 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)
可以使用正确的指针算法修复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。
&
中的push(stk_handle, &(string1));
操作是不必要的,你可以写一下
push(stk_handle, string1);
push(stk_handle, string2);
push(stk_handle, string3);