Created
September 13, 2012 10:52
-
-
Save sshtmc/3713552 to your computer and use it in GitHub Desktop.
Simple vector-implementation in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef __SIMPLECVECTOR_H__ | |
#define __SIMPLECVECTOR_H__ | |
#include <stdlib.h> | |
#include <assert.h> | |
#include <string.h> | |
typedef struct vector_ { | |
void** data; | |
size_t used_entries; | |
size_t capacity; | |
} vector; | |
// Return the vector size | |
static inline size_t vector_size(vector *v) | |
{ | |
return v->used_entries; | |
} | |
// Grow the vector to at least this size | |
static inline void vector_grow(vector *v, size_t new_size) | |
{ | |
while (v->capacity < new_size) | |
v->capacity *= 2; | |
v->data = realloc(v->data, sizeof(void*) * v->capacity); | |
assert(v->data); | |
// set all unused values to zero (potential performance hazard!) | |
// memset(v->data+v->used_entries, 0, sizeof(void) * (v->capacity - v->used_entries)); | |
} | |
// APPEND an element to a vector, may grow the vector | |
static inline void vector_append(vector *v, void *e) | |
{ | |
// condition to increase v->data: | |
// last slot exhausted | |
if (v->used_entries >= v->capacity) { | |
vector_grow(v, v->capacity*2); | |
} | |
v->data[v->used_entries] = e; | |
v->used_entries++; | |
} | |
// SET an element at index to 'e' | |
static inline void vector_set(vector *v, size_t index, void *e) | |
{ | |
if (index >= v->capacity) { | |
vector_grow(v, index); | |
return; | |
} | |
v->data[index] = e; | |
} | |
// GET an element at index | |
static inline void *vector_get(vector *v, size_t index) | |
{ | |
if (index >= v->used_entries) { | |
return NULL; | |
} | |
return v->data[index]; | |
} | |
// POPs an element at index; COSTLY OPERATION, AVOID IF POSSIBLE! | |
static inline void *vector_pop(vector *v, size_t index) | |
{ | |
if (index >= v->used_entries) { | |
return NULL; | |
} | |
void *ret = v->data[index]; | |
size_t i, j; | |
void **newarr = (void**)malloc(sizeof(void*) * v->capacity); | |
for (i = 0, j = 0; i < v->used_entries; i++) { | |
if (i == index) continue; | |
// at one moment, when i>index, 'i' will get in front of 'j' | |
newarr[j] = v->data[i]; | |
j++; | |
} | |
free(v->data); | |
v->data = newarr; | |
v->used_entries--; | |
return ret; | |
} | |
// initialize the vector, give it some capacity an allocate space | |
static inline void vector_init(vector *v) | |
{ | |
v->used_entries = 0; | |
v->capacity = 10; | |
v->data = calloc(sizeof(void*), v->capacity); | |
} | |
// release the vector | |
static inline void vector_free(vector *v) | |
{ | |
free(v->data); | |
} | |
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include "simple_c_vector.h" | |
int main(void) | |
{ | |
vector v; | |
vector_init(&v); | |
vector_append(&v, "emil"); | |
vector_append(&v, "hannes"); | |
vector_append(&v, "lydia"); | |
vector_append(&v, "olle"); | |
vector_append(&v, "erik"); | |
size_t i; | |
printf("first round:\n"); | |
for (i = 0; i < vector_size(&v); i++) { | |
printf("%s\n", (const char *)vector_get(&v, i)); | |
} | |
vector_pop(&v, 1); | |
vector_pop(&v, 3); | |
printf("second round:\n"); | |
for (i = 0; i < vector_size(&v); i++) { | |
printf("%s\n", (const char *)vector_get(&v, i)); | |
} | |
vector_free(&v); | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment