I saw quite a few posts about making a dynamic array so I tried making my own for learning purposes.
Here it is:
#ifndef VECTOR_H
#define VECTOR_H
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#ifndef VECTOR_RESERVE_SIZE
#define VECTOR_RESERVE_SIZE 4
#endif
//Declaration
typedef struct
{
int size_of_each;
int reserved;
int used;
void* data;
} vector_t;
bool vector_init(vector_t *, int);
void vector_append(vector_t *, void *);
void* vector_get(vector_t *, int );
void vector_set(vector_t *, int, void *);
void vector_free(vector_t *);
//Implementation
bool vector_init(vector_t *p, int s)
{
p->size_of_each = s;
p->reserved = VECTOR_RESERVE_SIZE;
p->used = 0;
p->data = malloc(VECTOR_RESERVE_SIZE * p->size_of_each);
if (p->data != NULL) { return false; }
else { return true; }
}
void vector_append(vector_t *p, void *d)
{
if (p->used == p->reserved)
{
p->data = realloc(p->data, VECTOR_RESERVE_SIZE);
//printf("reallocated \n");
p->reserved += VECTOR_RESERVE_SIZE;
}
memcpy((void*)((char*)p->data + p->size_of_each * p->used), // copy to back of the vector
d, p->size_of_each);
p->used += 1;
}
void* vector_get(vector_t *p, int i)
{
if (!(i > p->used))
{
return (void*)((char*)p->data + p->size_of_each * i);
}
else { return NULL; }
}
void vector_set(vector_t *p, int i, void *d)
{
if (!(i > p->used))
{
memcpy((void*)((char*)p->data + p->size_of_each * i), d, p->size_of_each);
}
}
void vector_free(vector_t *p)
{
free(p->data);
}
#endif
Here is an example of its usage:
#include <stdio.h>
#define VECTOR_RESERVE_SIZE 3
#include "vector.h"
int main()
{
int a = 321;
int b = 45;
int c = 21;
int d = 31;
int e = 71;
vector_t v;
vector_init(&v, sizeof (int));
vector_append(&v, &a);
vector_append(&v, &b);
vector_append(&v, &c);
vector_append(&v, &d);
vector_append(&v, &e);
printf("1st element is %d \n", *(int*)vector_get(&v, 0));
printf("2nd element is %d \n", *(int*)vector_get(&v, 1));
printf("3th element is %d \n", *(int*)vector_get(&v, 2));
printf("4th element is %d \n", *(int*)vector_get(&v, 3));
printf("5th element is %d \n\n", *(int*)vector_get(&v, 4));
vector_set(&v, 4, &a);
printf("4th element after setting is %d \n\n", *(int*)vector_get(&v, 4));
//contiguous
printf("size of int is: %d \n", sizeof (int));
printf("address of 1st element: %p \n", vector_get(&v, 0));
printf("address of 2nd element: %p \n", vector_get(&v, 1));
printf("address of 3rd element: %p \n", vector_get(&v, 2));
printf("address of 4th element: %p \n", vector_get(&v, 3));
printf("address of 5th element: %p \n", vector_get(&v, 4));
vector_free(&v);
}
I've written some C++ before and this was one of my first few projects in C.
I'd like to know overall how good my code is and whether I'm using good practices / conventions.
Edit:
this:
p->data = realloc(p->data, VECTOR_RESERVE_SIZE);
should be this:
p->data = realloc(p->data, (p->reserved + VECTOR_RSERVE_SIZE) * P->size_of_each);
Edit: Maybe it's too late but, if people are still reviewing this I would really like to know how does this approach compare to std::vector.