Create your own dynamic array in C language or use a library

In C language, there is a method to dynamically allocate memory with static array, but since there is no dynamic array library, you can create your own or library. Is used.

The reason why there is no frequently used library called dynamic array is that there is a policy that libraries that require memory allocation inside the library are not included in the core of C language.

Used in the internal implementation of the programming language SPVM as an example of a dynamic array I will write an implementation example of the dynamic array as a sample.

There are no dependencies, so you can copy and paste the header and source.

Implementation example of dynamic array in C language

There is no explanation, but since it is only the basic functions of creating a dynamic array, getting and setting the elements of the array, and fetching from the beginning and end, you can see how to use it by looking at the header. The elements of the array are general-purpose pointer type void *.

spvm_list.h

Dynamic array header.

#ifndef SPVM_LIST_H
#define SPVM_LIST_H

#include <stdint.h>
#include <stddef.h>

struct spvm_list;
typedef struct spvm_list SPVM_LIST;

struct spvm_list {
  void ** values;
  int32_t length;
  int32_t capacity;
};;

SPVM_LIST * SPVM_LIST_new (int32_t capacity);
void SPVM_LIST_free (SPVM_LIST * array);
void SPVM_LIST_maybe_extend (SPVM_LIST * array);

void SPVM_LIST_push (SPVM_LIST * array, void * value);
void * SPVM_LIST_fetch (SPVM_LIST * array, int32_t index);
void SPVM_LIST_store (SPVM_LIST * array, int32_t index, void * value);
void * SPVM_LIST_pop (SPVM_LIST * array);
void * SPVM_LIST_shift (SPVM_LIST * array);

#endif

spvm_list.c

An implementation of a dynamic array.

#include <string.h>
#include <stdlib.h>
#include <assert.h>

#include "spvm_list.h"

SPVM_LIST * SPVM_LIST_new (int32_t capacity) {
  
  assert (capacity> = 0);
  
  SPVM_LIST * array = calloc (1, sizeof (SPVM_LIST));
  
  array->length= 0;
  
  if (capacity == 0) {
    array->capacity= 1;
  }
  else {
    array->capacity= capacity;
  }
  
  void ** values ​​= calloc (array->capacity, sizeof (void *));
  
  array->values​​= values;
  
  return array;
}

void SPVM_LIST_maybe_extend (SPVM_LIST * array) {
  
  assert (array);
  
  int32_t length = array->length;
  int32_t capacity = array->capacity;
  
  if (length> = capacity) {
    int32_t new_capacity = capacity * 2;
    
    void ** new_values ​​= calloc (new_capacity, sizeof (void *));
    memcpy (new_values, array->values, capacity * sizeof (void *));
    free (array->values);
    array->values​​= new_values;
    
    array->capacity= new_capacity;
  }
}

void SPVM_LIST_free (SPVM_LIST * array) {
  
  free (array->values);
  free (array);
}

void SPVM_LIST_push (SPVM_LIST * array, void * value) {
  
  SPVM_LIST_maybe_extend (array);
  
  int32_t length = array->length;
  
  * (void **) & array->values​​[length] = value;
  array->length++;
}

void * SPVM_LIST_fetch (SPVM_LIST * array, int32_t index) {
  assert (array);
  assert (index> = 0);
  assert (index <array->length);
  
  
  return * (void **) & array->values​​[index];
}

void SPVM_LIST_store (SPVM_LIST * array, int32_t index, void * value) {
  
  assert (array);
  assert (index> = 0);
  assert (index <array->length);
  
  * (void **) & array->values​​[index] = value;
}

void * SPVM_LIST_pop (SPVM_LIST * array) {
  
  assert (array->length> = 0);
  
  if (array->length== 0) {
    return NULL;
  }
  else {
    array->length-;
    return * (void **) & array->values​​[array->length];
  }
}

void * SPVM_LIST_shift (SPVM_LIST * array) {
  
  assert (array->length> = 0);
  
  if (array->length== 0) {
    return NULL;
  }
  else {
    void * return_value = array->values​​[0];
    for (int32_t i = 0; i <array->length--1; i ++) {
      array->values​​[i] = array->values​​[i + 1];
    }

    array->length-;
    return return_value;
  }
}

Associated Information