7

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;
}
4
  • 4
    sizeof(listptr->elementSize)? Really? Commented May 28, 2016 at 7:17
  • 1
    malloc() returns a pointer, why are you assigning a pointer to listptr? Commented May 28, 2016 at 8:22
  • @n.m. Thanks for fixing the code! Commented May 28, 2016 at 8:44
  • suggest have to array element contains a void* to the actual data. Then the program that is using that list it can interpret the data in what ever manner fits the application. Commented May 28, 2016 at 20:10

1 Answer 1

6

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
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for correcting me. I remove the sizeof(), it now works for double, but string type (char *) still doesn't work, it keeps printing weird symbol
Beware, if you only store the pointer to the string, you must ensure the array is not destroyed before you use it (this is called dangling pointer, just google for that...)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.