2016-11-14 2 views
1

Ich versuche einen generischen Stack zu erstellen, aber meine Pop-Methode scheint falsch zu sein, weil sie die Zahlen von 100 auf 1 und die 1 verdoppelt. Wenn ich die Pop-Methode zu dieser Lösung zu ändern: Generic Stacks in C es knallt auf 64 und dann nur 64 mal 0Generic Stack hört auf, Werte zu knacken

Struktur:

typedef struct { 
    void *elems; 
    int elemSize; 
    int logLength; 
    int allocLength; 
    void (*freefn)(void*); 
} genStack; 

C-Quelldatei:

#include "genstacklib.h" 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <assert.h> 

void GenStackNew(genStack *s, int elemSize, void(*freefn)(void *)) { 
    s->elemSize = elemSize; 
    s->elems = malloc(4 * s->elemSize); 
    if (s->elems == NULL) { 
     perror("\n\nError: "); 
    } 
    s->allocLength = 4 * s->elemSize; 
    s->logLength = 0; 
    s->freefn = freefn; 
} 

void GenStackDispose(genStack *s) { 
    if (s->elems == NULL) { 
     printf("\n\nStack is not initialized!\n\n"); 
     return; 
    } 
    /*if (s->freefn != NULL) { 
     int n = 0; 
     while (s->logLength != 0) { 
      freefn(s->elems + n * s->elemSize); 
      n++; 
     } 
    }*/ 
    free(s->elems); 
} 

bool GenStackEmpty(const genStack *s) { 
    if (s->logLength == 0) { 
     return true; 
    } else { 
     return false; 
    } 
} 

void GenStackPush(genStack *s, const void *elemAddr) { 
    if (s->elems == NULL) { 
     printf("\n\nStack not initialized!\n\n"); 
     return; 
    } 
    if (s->allocLength == s->logLength * s->elemSize) { 
     s->allocLength = 2*s->allocLength; 
     s->elems = realloc(s->elems, s->allocLength*s->elemSize); 
    } 
    memcpy(s->elems+s->logLength*s->elemSize,elemAddr,s->elemSize); 
    s->logLength++; 
} 

void GenStackPop(genStack *s, void *elemAddr) { 
    void *source = s->elems + (s->logLength-1)*s->elemSize; 
    memcpy(elemAddr,source,s->elemSize); 
    memcpy(s->elems,source,s->elemSize); 
    s->logLength--; 
    //memcpy((char*)s->elems+(s->logLength-1)*s->elemSize,elemAddr,s->elemSize); 
} 

Teststack (sollte Zahlen von 0 bis 100 drücken und danach wieder loslassen):

Antwort

1

Der zweite Memcpy Aufruf in der GenStackPop Funktion scheint überflüssig und tut nichts anderes als das erste Element clobber:

memcpy(s->elems,source,s->elemSize); 
1

Nun, bekomme ich Compiler-Warnungen, dass die Größe von void * ist nicht erforderlich, wenn bekannt. Diese occurrs in:

memcpy(s->elems+s->logLength*s->elemSize,elemAddr,s->elemSize); 

wie Sie + auf s->elems und in Pop verwenden.

Ändern void *elems; in der Struktur-Deklaration zu char *elems; und es funktioniert OK.

+0

OP verwendet eine Compiler-Erweiterung. – 2501

+0

@ 2501, diese Erweiterungen entsprechen auf diese Fälle 'void *' zu 'char *'? –

+0

https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html – 2501