Skip to content
Ilya Kashnitskiy edited this page Jan 22, 2020 · 7 revisions

My own implementation of a dynamic array on C. Named after the vector in C++.

This is the header with API: ft_vector.h and this is the implementation folder: sources/ft_vector/

  • Structure

typedef struct		s_vector
{
	void *restrict	mem;
	size_t		item_size;
	size_t		curlen;
	size_t		max_len;
}			t_vect;
  • mem : pointer to memory with items
  • item_size : size of each item in bytes
  • cur_len : current vector length (number of elements)
  • max_len : size of reserved memory (number of elements)

This is a dynamic structure! If the reserved memory is over, reallocation will be made with a 2-fold increase in size!

  • Functions

Definition Description
void vect_init(t_vect *restrict self, size_t item_size, size_t init_len) Initializes the vector self. init_len - initial size of vector (number of elements), must be > 0.
void vect_del(t_vect *restrict self) Free memory and fill self by zero.
void vect_extend(t_vect *restrict self, size_t n) Extends the vector to fit self->curlen + n elements.
void vect_shrink(t_vect *restrict self, size_t reserve) Shrink the vector to fit no more then self->curlen + reserve elements.
void vect_clean(t_vect *self) Fills all allocated memory with zeros and set self->curlen = 0.
void *vect(t_vect *restrict self, size_t i) Returns pointer to thei-th element of a vector.
size_t vect_i(t_vect *restrict self, void *item) Returns the index of the item in the vector.
void *vect_top(t_vect *restrict self) Returns the last (self->curlen-th) element of a vector.
void *vect_(t_vect *restrict self, long long int i) Accepts both positive and negative i. Returns pointer to thei-th element of a vector, where positive i calc like self->curlen - 1 - i-th element and negative i calc like -1 + ABS(i)-th element.
void *vect_eq(t_vect *restrict self, size_t i, void *data) Reads self->item_size bytes from data and writes it in i-th element of vector.
void *vect_add(t_vect *restrict self, void *data) Adds an element from data to the end of the vector. Extends vector if necessary.
void *vect_add_i(t_vect *restrict self, void *data, size_t i) Adds an element from data to the i-th position of the vector. Extends vector if necessary.
void *vect_add_n(t_vect *restrict self, void *data, size_t n) Adds n elements from data to the end of the vector. Extends vector if necessary.
void *vect_add_mem(t_vect *restrict self, void *data, size_t len) Allocs len bytes, copy len bytes from data and add new pointer to vector. self->item_size must be at least PTR_SIZE bytes (vector store pointers).
void *vect_pop(t_vect *restrict self); Removes and returns pointer to the item at the and of the vector. Save the data from this pointer, otherwise it will be lost.
void *vect_pop_i(t_vect *restrict self, size_t i) Removes and returns pointer to the i-th item of the vector. Save the data from this pointer, otherwise it will be lost.
void *vect_pop_p(t_vect *restrict self, void *item) Removes and returns item from the vector. Save the data from this pointer, otherwise it will be lost.
void *vect_find_back(t_vect *restrict self, void *data, int (*cmp)(const void *, const void *)) Iterates over the entire vector from the end, comparing each element with data using cmp. Returns the item on the first matching item. NULL otherwise.
void *vect_find_front(t_vect *restrict self, void *data, int (*cmp)(const void *, const void *)) Iterates over the entire vector from the beginning, comparing each element with data using cmp. Returns the item on the first matching item. NULL otherwise.
void vect_map(t_vect *restrict self, void (*func)(void *)) Iterates over the entire vector from the beginning, applying the func function to each element.
void vect_sort(t_vect *restrict self, int (*cmp)(const void *, const void *), void (*sort)(void *, size_t, size_t, int (*cmp)(const void *, const void *))) Sorted vector.
size_t vect_bin_find(t_vect *self, void *data, int (*cmp)(const void *, const void *)) Binary search by vector. Returns i + 1 - index of the found element + 1, 0 otherwise.
  • Example №1

#include <libft.h>

#include <stdlib.h>
#include <time.h>

void	print(void *data)
{
	ft_printf("%d ", *(int *)data);
}

void	example(size_t x)
{
	t_vect	vector[1];

	vect_init(vector, sizeof(int), 1);
	for(size_t i = 0; i < x; i++)
		vect_add(vector, ft_i(rand() % 256));
	vect_map(vector, print);
	ft_printf("\n");
	vect_sort(vector, ft_icmp, ft_qsort);
	vect_map(vector, print);
	ft_printf("\n");
	vect_del(vector);
	return ;
}

int	main(int argc, char **argv)
{
	size_t	x ;

	ft_memman_init();
	srand(time(0));

	x = (argc == 2) ? (size_t)ft_atoi(argv[1]) : 5;
	example(x);
	
	ft_force_buff();
	ft_memman_clean();
	return (0);
}

Output:

> a.out
177 18 94 234 33 
18 33 94 177 234
> a.out 15
77 215 197 148 43 224 54 241 55 253 8 117 34 30 135 
8 30 34 43 54 55 77 117 135 148 197 215 224 241 253

If you cannot get a pointer to the value to be added to the vector, use ft_eval.h

You can also find ready-made comparison functions in ft_cmp.h

  • Example №2

#include <libft.h>

void	print(void *data)
{
	ft_printf("\"%s\" ", *(char **)data);
}

void	del_mem(void *data)
{
	ft_memdel((void **)data);
}

void	fill_data(t_vect *vector)
{
	int	ret;
	char	*line;

	vect_add_mem(vector, "under this str need alloc memory!", 34);
	while ((ret = ft_get_next_line(0, &line)) > 0)
		vect_add(vector, &line);
	ft_memdel((void **)&line);
}

void	print_data(t_vect *vector)
{
	char	*tmp;

	vect_map(vector, print);
	ft_printf("\n");
	vect_sort(vector, ft_scmp, ft_qsort);
	vect_map(vector, print);
	ft_printf("\n");
	if (vector->curlen > 0)
	{
		tmp = *(char **)vect_pop(vector);
		vect_add_i(vector, &tmp, 0);
	}
	if (vector->curlen > 3)
		ft_memdel(vect_pop_i(vector, 2));
	vect_map(vector, print);
	ft_printf("\n");
	return ;
}

int	main(void)
{
	t_vect	vector[1];

	ft_memman_init();

	vect_init(vector, PTR_SIZE, 1);
	fill_data(vector);
	print_data(vector);
	vect_map(vector, del_mem);
	vect_del(vector);

	ft_force_buff();
	ft_memman_clean();
	return (0);
}

Output:

> a.out
> beee
> abcd
> qwerty
> fghj
> caar
"under this str need alloc memory!" "beee" "abcd" "qwerty" "fghj" "caar" 
"abcd" "beee" "caar" "fghj" "qwerty" "under this str need alloc memory!" 
"under this str need alloc memory!" "abcd" "caar" "fghj" "qwerty"

GO TO NEXT PAGE --->