我正在尝试在普通C中创建一个通用堆栈,我有一些指针问题,不知道问题出在哪里。
这是我遇到问题的结构和功能:
typedef struct{
void *elems;
int elemSize;
int logLength;
int allocLength;
} genStack;
void GenStackPush(genStack *s, const void *elemAddr);
void GenStackPop(genStack *s, void *elemAddr);
这就是实施:
void GenStackPush(genStack *s, const void *elemAddr)
{
s->elems[s->logLength] = elemAddr;
s->logLength++;
}
void GenStackPop(genStack *s, void *elemAddr)
{
s->logLength--;
elemAddr = s->elems[s->logLength];
}
用法应如下所示:
int val;
genStack IntegerStack;
for (val = 0; val < 6; val++)
GenStackPush(&IntegerStack, &val);
GenStackPop(&IntegerStack, &val);
printf("Popped: %d\n",val);
以下是我遇到的问题:
genstacklib.c: In function ‘GenStackPush’:
genstacklib.c:60:10: warning: dereferencing ‘void *’ pointer [enabled by default]
genstacklib.c:60:2: error: invalid use of void expression
genstacklib.c: In function ‘GenStackPop’:
genstacklib.c:72:23: warning: dereferencing ‘void *’ pointer [enabled by default]
genstacklib.c:72:13: error: void value not ignored as it ought to be
我已经尝试了几种方法来修复代码,但是没有一种方法可以工作。 感谢。
=============================================== ===========================
所以,伙计们,谢谢你的帮助!现在它编译,但我已经改变了一个API,由我们的教授给出。 'const'限定符也有问题,所以我删除了它们。不是我的代码看起来像这样:
genstacklib.h:
#ifndef GENSTACKLIB_H
#define GENSTACKLIB_H
#define GenStackInitialAlocationSize 4
typedef struct{
void** elems;
int elemSize;
int logLength;
int allocLength;
}genStack;
void GenStackNew(genStack *s,int elemSize);
void GenStackDispose(genStack *s);
int GenStackEmpty(const genStack *s);
void GenStackPush(genStack *s, void *elemAddr);
void GenStackPop(genStack *s, void *elemAddr);
#endif
genstacklib.c:
#include <stdlib.h>
#include <stdio.h>
#include "genstacklib.h"
void GenStackNew(genStack *s,int elemSize)
{
void** newElems;
/* Allocate a new array to hold the contents. */
newElems = (void**) malloc(elemSize * GenStackInitialAlocationSize);
if (newElems == NULL)
{
fprintf(stderr, "Error with allocating the stack.\n");
exit(1); /* Exit, returning error code. */
}
s->elems = newElems;
s->allocLength = GenStackInitialAlocationSize;
s->logLength = 0; /*is empty*/
}
void GenStackDispose(genStack *s)
{
s->allocLength = 0;
free(s->elems);
}
int GenStackEmpty(const genStack *s)
{
return s->logLength == 0;
}
void GenStackPush(genStack *s, void *elemAddr)
{
s->elems[s->logLength] = elemAddr;
s->logLength++;
}
void GenStackPop(genStack *s, void *elemAddr)
{
s->logLength--;
elemAddr = s->elems[s->logLength];
}
如果你有什么想法可以改进或者说些什么,我会高兴地听到。 :d
答案 0 :(得分:3)
你试图取消引用void指针而不将类型转换为造成问题的其他类型。
答案 1 :(得分:1)
elems的类型错误。如果将其声明为void*
,则编译器不知道它指向的内容有多大。因此它不能对其进行指针运算或数组下标,甚至不能取消引用它指向的内容。
概念上,elems是你放在堆栈上的东西的数组。你把什么放在堆栈上?指针 - 声明为void*
。所以elems应该是void*
个对象的数组。你可以像这样声明它
typedef struct{
void *elems[STACK_SIZE];
int elemSize;
int logLength;
int allocLength;
} genStack;
将在数组的结构中保留空间(使结构本身非常大),或者您可以将其声明为指向void*
的指针,即void**
typedef struct{
void **elems;
int elemSize;
int logLength;
int allocLength;
} genStack;
如果选择此选项,则必须手动分配内存
genStack* genStackAlloc()
{
genStack* ret = calloc(1, sizeof *ret);
ret->elemns = calloc(STACK_SIZE, sizeof(void*));
// rest of the initialisation
return ret;
}
当然,处理堆栈时你必须手动释放内存。
答案 2 :(得分:0)
elems
被声明为指向void
的指针,我认为您希望它是指向void*
的指针。
答案 3 :(得分:0)
问题是s->elems[s->logLength]
:
首先,成员变量void * elems用于存储元素地址(void *),元素数组(void ),因此elems的类型应为(void * ),你应该分配内存来存储地址。
您可以通过以下方式分配内存:
void * elems[MAX_STACK_SIZE];
OR
void ** elems
s->elems = (void**)malloc(MAX_STACK_SIZE*sizeof(void*)); // and allocate it before use it.