1

我正在尝试用纯 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

4

4 回答 4

3

您正在尝试取消引用 void 指针而不强制转换为导致问题的其他类型。

于 2012-04-06T13:44:14.743 回答
1

elems 的类型错误。如果你把它声明为void*编译器不知道它指向的东西有多大。所以它不能对其进行指针算术或数组下标,甚至不能取消引用它所指向的内容。

从概念上讲,elems 是您放入堆栈的一系列内容。你把什么放在堆栈上?指针 - 声明为void*. 所以 elems 应该是一个void*对象数组。你可以这样声明

typedef struct{
    void *elems[STACK_SIZE]; 
    int elemSize; 
    int logLength; 
    int allocLength;
} genStack;

这将在结构中为数组保留空间(使结构本身非常大),或者您可以将其声明为指向void*ievoid**

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;
}

当然,您必须在处理堆栈时手动释放内存。

于 2012-04-06T14:05:54.760 回答
0

elems被声明为指向 a 的指针void,我认为您希望它是指向 a 的指针void*

于 2012-04-06T13:32:49.953 回答
0

问题是s->elems[s->logLength]

首先,成员变量void *elems用于存储元素地址(void *),元素数组(void ),所以elems的类型应该是(void *),你应该分配内存来存储地址.

您可以通过以下方式分配内存:

void * elems[MAX_STACK_SIZE];

或者

void ** elems    
s->elems = (void**)malloc(MAX_STACK_SIZE*sizeof(void*)); // and allocate it before use it.
于 2012-04-06T14:06:52.417 回答