Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C generic array implementation

I am trying to implement a generic array list in C. However, when the data type is any type other than int, the list wont contain the correct data. For example, like 123.1234 as a double, when the double is passed into the list, it will become 000.0000. One when the data type is int, it will have correct value. I don't know which part of the code is wrong, can anyone give me a hint? Thanks

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "genericADT.h"

struct list_type {
   void *data;
   int elementSize;
   int size;
   int capacity;
};

ListType create(int elementSize) {
   ListType listptr = malloc(sizeof(struct list_type));

   if (listptr != NULL) {
      listptr->size = 0;
      listptr->capacity = 10;
      listptr->elementSize = elementSize;
      listptr->data = malloc(10 * (listptr->elementSize));
      if (listptr->data == NULL) {
         free(listptr);
         listptr = NULL;
      }
   }
   return listptr;
}

void push(ListType listptr, void *item) {
   if (listptr->size >= listptr->capacity) {
      void *temp = realloc(listptr->data, listptr->elementSize * (listptr->capacity + 100));
      if (temp != NULL) {
         listptr->capacity += 100;
         listptr->data = temp;

         memcpy(listptr->data + (listptr->size) * (listptr->elementSize), item, sizeof(listptr->elementSize));
         listptr->size++;
      }
   } else {
      memcpy(listptr->data + (listptr->size) * (listptr->elementSize), item, sizeof(listptr->elementSize));
      listptr->size++;
   }
}

void *get(ListType listptr, int index) {
   return listptr->data + index * (listptr->elementSize);
}

int size_is(ListType listptr) {
   return listptr->size;
}
like image 311
Ming Avatar asked May 28 '16 07:05

Ming


Video Answer


1 Answers

There are minor problems in your code, but it correctly processes double values.

First as noticed by @n.m., you really want to use listptr->elementSize instead of sizeof(listptr->elementSize)

Next, as you want to do pointer arithmetic, you should declare data as char * and not void *

Last as a elementary optimization, you pull the actual insertion code after the test for capacity instead of duplicating it in both branches.

But after those fixes, this main correctly stores and extract double:

int main() {
    ListType ls = create(sizeof(double));
    double f1=1.5, f2=3.6;
    push(ls, &f1);
    push(ls, &f2);
    printf("Got %f %f\n", *((double *) get(ls, 0)), *((double *) get(ls, 1)));
    return 0;
}

it prints as expected:

Got 1.500000 3.600000
like image 65
Serge Ballesta Avatar answered Oct 23 '22 19:10

Serge Ballesta