Although I know I can use calloc
then realloc
to make a dynamic array in C, and that I also need a variable to keep track of the number of elements in the array, that isn't too productive to me. Coming from an object oriented background using other high level languages (Namely Java and Python), I decided that an arraylist would fit my needs. In C ofcourse, that'd mean that behind the curtains, I'd probably be using a dynamic array which I'd be realloc
ing every time I add a member to it, that member would be a pointer to another variable.
The Header
#ifndef _ARRAYLIST_H
#define _ARRAYLIST_H
typedef struct _arraylist ArrayList;
extern ArrayList *arraylist_create();
extern void arraylist_set_data(ArrayList *, void **);
extern void arraylist_add(ArrayList *, void *);
extern void *arraylist_get(ArrayList *, int);
extern void arraylist_remove(ArrayList *, int);
extern void arraylist_clear(ArrayList *);
extern void arraylist_deallocate(ArrayList *);
#endif /* _ARRAYLIST_H */
The Source
#include <stdlib.h>
#include <assert.h>
#include "ArrayList.h"
struct _arraylist {
size_t size;
size_t data_size;
void ** data;
};
struct _arraylist *arraylist_create() {
/* Allocate Memory */
struct _arraylist *list = malloc(sizeof(struct _arraylist));
assert(list != NULL);
list->size = 0;
list->data_size = 0;
list->data = calloc(2, sizeof(void *));
assert(list->data != NULL);
list->data[0] = NULL;
return list;
}
void arraylist_set_data(struct _arraylist *list, void ** data) {
arraylist_clear(list);
list->data = data;
for(int i = 0; ( list->data[i] != NULL ); ++i) {
list->data_size += sizeof(*list->data[i]);
++list->size;
}
}
void arraylist_add(struct _arraylist *list, void *elem) {
list->data_size += sizeof(*elem);
void ** new_data = realloc(list->data, (list->size + 1) * (list->data_size));
assert(new_data != NULL);
new_data[list->size] = elem;
new_data[list->size + 1] = NULL;
arraylist_set_data(list, new_data);
++list->size;
}
void *arraylist_get(struct _arraylist *list, int index) {
return list->data[index];
}
void arraylist_remove(struct _arraylist *list, int index) {
list->data_size -= sizeof( *arraylist_get( list, index ) );
for ( int i = index; list->data[i + 1] != NULL; ++i )
list->data[i] = list->data[i + 1];
list->data[list->size] = NULL;
void ** new_data = realloc(list->data, list->size * list->data_size);
assert(new_data != NULL);
arraylist_set_data(list, new_data);
--list->size;
}
void arraylist_clear(struct _arraylist *list) {
/* free(list->data); */ /* Problem here */
list->size = 0;
list->data_size = 0;
list->data = NULL;
}
void arraylist_deallocate(struct _arraylist *list) {
arraylist_clear(list);
free(list);
}
The code works fine, but there are a few problems I've faced so far.
If I want to add a member, I can't initialize a variable immediately, because I have to pass a pointer to an existing variable.
The first line in the
arraylist_clear
function causes a problem when running the problem, and without it (as valgrind says) I have a slight memory leak that I don't know how to deal with.The
arraylist_remove
function doesn't work.
arraylist_remove
function doesn't work that this question is considered off-topic. – syb0rg Sep 30 '14 at 19:18