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*つまりへのポインターとして宣言することもできます。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;
}

もちろん、スタックを破棄するときは手動でメモリを解放する必要があります。

于 2012-04-06T14:05:54.760 に答える
0

問題はs->elems[s->logLength]

まず、メンバー変数void * elemsは要素アドレス(void *)、要素の配列(void )を格納するために使用するため、要素のタイプは(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 に答える
0

elemsへのポインターとして宣言されていますvoid。ここで、 へのポインターにしたいと思いますvoid*

于 2012-04-06T13:32:49.953 に答える