Instantly share code, notes, and snippets.

Embed
What would you like to do?
Simple vector-implementation in C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "vector.h"
void vector_init(vector *v)
{
v->data = NULL;
v->size = 0;
v->count = 0;
}
int vector_count(vector *v)
{
return v->count;
}
void vector_add(vector *v, void *e)
{
if (v->size == 0) {
v->size = 10;
v->data = malloc(sizeof(void*) * v->size);
memset(v->data, '\0', sizeof(void*) * v->size);
}
if (v->size == v->count) {
v->size *= 2;
v->data = realloc(v->data, sizeof(void*) * v->size);
}
v->data[v->count] = e;
v->count++;
}
void vector_set(vector *v, int index, void *e)
{
if (index >= v->count) {
return;
}
v->data[index] = e;
}
void *vector_get(vector *v, int index)
{
if (index >= v->count) {
return NULL;
}
return v->data[index];
}
void vector_delete(vector *v, int index)
{
if (index >= v->count) {
return;
}
for (int i = index, j = index; i < v->count; i++) {
v->data[j] = v->data[i];
j++;
}
v->count--;
}
void vector_free(vector *v)
{
free(v->data);
}
int main(void)
{
vector v;
vector_init(&v);
vector_add(&v, "emil");
vector_add(&v, "hannes");
vector_add(&v, "lydia");
vector_add(&v, "olle");
vector_add(&v, "erik");
int i;
printf("first round:\n");
for (i = 0; i < vector_count(&v); i++) {
printf("%s\n", (char*)vector_get(&v, i));
}
vector_delete(&v, 1);
vector_delete(&v, 3);
printf("second round:\n");
for (i = 0; i < vector_count(&v); i++) {
printf("%s\n", (char*)vector_get(&v, i));
}
vector_free(&v);
return 0;
}
#ifndef VECTOR_H__
#define VECTOR_H__
typedef struct vector_ {
void** data;
int size;
int count;
} vector;
void vector_init(vector*);
int vector_count(vector*);
void vector_add(vector*, void*);
void vector_set(vector*, int, void*);
void *vector_get(vector*, int);
void vector_delete(vector*, int);
void vector_free(vector*);
#endif
@sshtmc

This comment has been minimized.

Copy link

sshtmc commented Sep 18, 2012

Do you have a license in mind for this gist? Can we assume it's an MIT license?

@bart113

This comment has been minimized.

Copy link

bart113 commented Jan 28, 2013

There is a bug in vector_delete. The v->size should be updated after new array is allocated (because it has different size than the old one). This leads to memory leaks and/or segfaults.

@cli248

This comment has been minimized.

Copy link

cli248 commented May 27, 2013

for vector_add, is it should be "memset(v->data, '\0', sizeof(void *) * v->size)", not sizeof(void)

@darelf

This comment has been minimized.

Copy link

darelf commented Dec 18, 2013

vector_delete doesn't have to reallocate a new memory block. Especially if you aren't changing the size of the array and are only allowing one item to be deleted at a time, then just start at the index that you are going to delete and shift everything down one, setting the last index to NULL.

@EmilHernvall

This comment has been minimized.

Copy link
Owner

EmilHernvall commented Mar 3, 2016

Just now noticed that people are using this. Sorry about the bugs -- I originally wrote this a long time ago, and wasn't a very accomplished C programmer at that point. I've revisited the code and fixed the bugs. Feel free to use the code under MIT license, if you wish.

@Gonw

This comment has been minimized.

Copy link

Gonw commented Apr 5, 2016

i think line 60 "for (int i = index, j = index; i < v->count; i++) {" should be "for (int i = index+1, j = index; i < v->count; i++) {".

@etochy

This comment has been minimized.

Copy link

etochy commented Feb 20, 2017

For the void delete, index is useless in your implementation and just delete the last object onto the vector. You should do this to fix this bug :
void vector_delete(vector *v, int index)
{
if (index >= v->count) {
return;
}
for (int i = index +1, j = index; i < v->count; ++i) {
printf("i : %d , j : %d\n",i,j );
v->data[j] = v->data[i];
++j;
}
v->count--;
}

@scarface382

This comment has been minimized.

Copy link

scarface382 commented Apr 23, 2017

You have made a vector that holds pointers, not actual values. So it's not a vector implementation.

@calxdesign

This comment has been minimized.

Copy link

calxdesign commented Nov 13, 2017

Thanks for this. Useful.

@matys18

This comment has been minimized.

Copy link

matys18 commented Jan 3, 2018

Be aware that on the off chance that you run out of memory, on line 30 realloc() can fail, in which case it will return a null pointer.

@Kagaratsch

This comment has been minimized.

Copy link

Kagaratsch commented Feb 18, 2018

I had to wrap all v->data[...] calls in parenthesis like (v->data)[...]. Otherwise the compiler was complaining that the subscript needs a pointer type.

@cinderblocks

This comment has been minimized.

Copy link

cinderblocks commented Jun 1, 2018

Line 49 should be return NULL;

@artistmonkey

This comment has been minimized.

Copy link

artistmonkey commented Aug 1, 2018

When I loop vector_add
vector_add(&v, "emil");
vector_add(&v, "hannes");
vector_add(&v, "lydia");
vector_add(&v, "olle");
vector_add(&v, "erik");

for (i = 0; i < 100; i++) {
	sprintf(ch,"hello%d",i);
	vector_add(&v, ch);
            printf("%s\n", (char*)vector_get(&v, i));
}

printf("first round:\n");
for (i = 0; i < vector_count(&v); i++) {
    printf("%s\n", (char*)vector_get(&v, i));
}

its all hello99 that added by loop. It is fine vector_get as soon as added.

@buguser

This comment has been minimized.

Copy link

buguser commented Oct 29, 2018

Nice code, thx!
Can anyone explain line 64?
As I read it, it allocates double as much memory as it hast elements, which doesn't correspond to the actual size..
shouldn't it be:
void **newarr = (void**)malloc(sizeof(void*) * v->size); ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment