Lukas Frey Lukas Frey - 24 days ago 9
C Question

Generic Stack stops popping values

I'm trying to build a generic stack but my pop-method seems wrong cause it prints the numbers from 100 to 1 and the 1 double.
If I change the pop-method to this solution: Generic Stacks in C it pops to 64 and then just 64 times 0.

struct:


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


C-Source file:


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


Test stack (should push numbers from 0 to 100 and pop it afterwards):


int main(int argc, char *argv[]) {

int val;
genStack IntegerStack;

GenStackNew(&IntegerStack, sizeof(int), NULL);
for (val = 0; val < 100; val++) {
GenStackPush(&IntegerStack, &val);
printf("Pushed: %d\n",val);
}

while(!GenStackEmpty(&IntegerStack)){
GenStackPop(&IntegerStack, &val);
printf("Popped: %d\n",val);
}

GenStackDispose(&IntegerStack);
}

Answer

The second memcpy call in the GenStackPop function seems redundant and does nothing but clobber the first element:

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