From 924c45e2231e02e8e73bfe6340846641ef78ec74 Mon Sep 17 00:00:00 2001 From: Andrew Haynes Date: Fri, 25 Sep 2026 12:57:12 -0400 Subject: [PATCH] REFACTOR: Resize is completely refactored and bug free --- "\\" | 629 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/char.c | 186 +++++++++++----- 2 files changed, 765 insertions(+), 50 deletions(-) create mode 100644 "\\" diff --git "a/\\" "b/\\" new file mode 100644 index 0000000..541299f --- /dev/null +++ "b/\\" @@ -0,0 +1,629 @@ +#include "char.h" + +#include +#include +#include +#include +#include + +#include "utils.h" + +int +is_valid(const Vec8_t* vec) +{ + if (vec == nullptr) + { + LOGERROR(ERR_VECTOR_NULL); + return ERR_VECTOR_NULL; + } + else if (vec->arr == nullptr) + { + LOGERROR(ERR_BUF_NULL); + return ERR_BUF_NULL; + } + return SUCCESS; +} + +Vec8_t +create(const char* buf, const size_t len) +{ + Vec8_t dst = { NULL, 0, CAPACITY, VEC_MAX }; + if (len > VEC_MAX) + { + LOGERROR(ERR_MAX_PASSED); + LOG("If you need more memory to start, create a blank and " + "reserve."); + return dst; + } + if (dst.capacity < len && len < dst.max_size) + { + if (dst.capacity * 2 > dst.max_size && len < dst.max_size) + { + dst.capacity = len; + } + while (dst.capacity < len && dst.capacity * 2 < dst.max_size) + dst.capacity *= 2; + } + if (len > 0) + { + char* dst_buf = calloc(dst.capacity, sizeof(char)); + if (!dst_buf) + { + LOGERROR(ERR_ALLOC_FAIL); + return dst; + } + dst.arr = dst_buf; + } + if (buf) + { + for (size_t i = 0; i < len; i++) + { + dst.arr[i] = buf[i]; + dst.size++; + } + } + return dst; +} + +Vec8_t +push_back(Vec8_t* ptr, const char val) +{ + if (is_valid(ptr) == ERR_VECTOR_NULL) + { + return create(nullptr, 0); + } + Vec8_t dst = { NULL, ptr->size, ptr->capacity, ptr->max_size }; + + if (is_valid(ptr) == ERR_BUF_NULL) + { + LOG("If you think this is wrong, reserve memory first"); + return dst; + } + if (ptr->size + 1 > ptr->max_size) + { + LOGERROR(ERR_MAX_PASSED); + dst = *ptr; + return dst; + } + + char* dst_buf; + if (ptr->size + 1 > ptr->capacity) + { + if (ptr->capacity * 2 > ptr->max_size) + { + LOGERROR(ERR_MAX_PASSED); + dst = *ptr; + return dst; + } + dst.capacity = ptr->capacity * 2; + dst_buf = realloc(ptr->arr, dst.capacity * sizeof(char)); + if (!dst_buf) + { + LOGERROR(ERR_ALLOC_FAIL); + dst = *ptr; + return dst; + } + } + else + { + dst_buf = ptr->arr; + } + dst.arr = dst_buf; + dst.arr[dst.size] = val; + dst.size++; + return dst; +} + +Vec8_t +pop_back(Vec8_t* ptr) +{ + Vec8_t err = create(nullptr, 0); + if (is_valid(ptr) != SUCCESS) + { + return err; + } + if (ptr->size < 1) + { + LOGERROR(ERR_SIZE_ZERO); + return err; + } + Vec8_t dst = { NULL, ptr->size - 1, ptr->capacity, ptr->max_size }; + dst.arr = ptr->arr; + dst.arr[dst.size] = 0; + return dst; +} + +Vec8_t +reserve(const Vec8_t* ptr, const size_t max_size) +{ + Vec8_t ret = create(nullptr, 0); + if (max_size == 0) + { + LOGERROR(ERR_SIZE_ZERO); + return ret; + } + if (is_valid(ptr) == ERR_VECTOR_NULL) + { + return ret; + } + ret.arr = ptr->arr; + if (is_valid(&ret) == ERR_BUF_NULL) + { + ret.arr = calloc(max_size, sizeof(char)); + if (!ret.arr) + { + LOGERROR(ERR_ALLOC_FAIL); + ret = *ptr; + return ret; + } + } + else if (is_valid(ptr) == SUCCESS) + { + ret.arr = realloc(ret.arr, max_size * sizeof(char)); + if (!ret.arr) + { + LOGERROR(ERR_ALLOC_FAIL); + ret = *ptr; + return ret; + } + ret.size = ptr->size; + if (ret.size > max_size) + { + for (size_t i = max_size; i < ret.size; i++) + { + ret.arr[i] = 0; + } + ret.size = max_size; + } + } + ret.capacity = max_size; + ret.max_size = max_size; + return ret; +} + +Vec8_t +shrink_to_fit(Vec8_t* ptr) +{ + if (is_valid(ptr) != SUCCESS) return create(nullptr, 0); + if (ptr->size == 0) + { + LOGERROR(ERR_SIZE_ZERO); + return create(nullptr, 0); + } + return reserve(ptr, ptr->size); +} + +int +swap(Vec8_t* ptr1, Vec8_t* ptr2) +{ + Vec8_t tmp = create(nullptr, 0); + if (is_valid(ptr1) == ERR_VECTOR_NULL || + is_valid(ptr2) == ERR_VECTOR_NULL) + { + return ERR_VECTOR_NULL; + } + if (is_valid(ptr1) == ERR_BUF_NULL || is_valid(ptr2) == ERR_BUF_NULL) + { + return ERR_BUF_NULL; + } + tmp.arr = ptr1->arr; + ptr1->arr = ptr2->arr; + ptr2->arr = tmp.arr; + + tmp.capacity = ptr1->capacity; + tmp.size = ptr1->size; + tmp.max_size = ptr1->max_size; + ptr1->capacity = ptr2->capacity; + ptr1->size = ptr2->size; + ptr1->max_size = ptr2->max_size; + + ptr2->capacity = tmp.capacity; + ptr2->size = tmp.size; + ptr2->max_size = tmp.max_size; + return SUCCESS; +} + +char* +data(const Vec8_t* ptr) +{ + if (is_valid(ptr) == ERR_BUF_NULL || is_valid(ptr) == ERR_VECTOR_NULL) + return nullptr; + return &ptr->arr[0]; +} + +size_t +capacity(const Vec8_t* ptr) +{ + if (is_valid(ptr) == ERR_VECTOR_NULL) + { + return ERR_VECTOR_NULL; + } + if (is_valid(ptr) == ERR_BUF_NULL) + { + return ERR_BUF_NULL; + } + return ptr->capacity; +} + +size_t +max_size(const Vec8_t* ptr) +{ + if (is_valid(ptr) == ERR_VECTOR_NULL) + { + return ERR_VECTOR_NULL; + } + if (is_valid(ptr) == ERR_BUF_NULL) + { + return ERR_BUF_NULL; + } + return ptr->max_size; +} + +void +delete(const Vec8_t* ptr) +{ + if (is_valid(ptr) == SUCCESS) + { + free((void*)ptr->arr); + } +} + +Vec8_t +clear(const Vec8_t* ptr) +{ + Vec8_t dst = create(nullptr, 0); + if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) + { + return dst; + } + dst = *ptr; + if (dst.size > 0) + { + for (size_t i = 0; i < dst.size; i++) + { + dst.arr[i] = 0; + } + dst.size = 0; + } + return dst; +} + +char +at(const Vec8_t* ptr, const size_t idx) +{ + if (is_valid(ptr) == ERR_VECTOR_NULL) + { + return ERR_VECTOR_NULL; + } + if (is_valid(ptr) == ERR_BUF_NULL) + { + return ERR_BUF_NULL; + } + if (idx >= ptr->size) + { + fprintf(stderr, + "At Index: [%zu] is out of bounds for size: [%zu]", idx, + ptr->size); + return ERR_OUT_OF_BOUNDS; + } + return ptr->arr[idx]; +} + +void +print_vec(const Vec8_t* ptr) +{ + if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) + return; + for (size_t i = 0; i < ptr->size; i++) printf("%c ", ptr->arr[i]); + printf("\n"); +} + +int +begin(const Vec8_t* ptr) +{ + if (is_valid(ptr) == SUCCESS) return 0; + return FAILURE; +} + +int +end(const Vec8_t* ptr) +{ + if (is_valid(ptr) == SUCCESS) + { + if (ptr->size != 0) return (int)(ptr->size - 1); + else return FAILURE; + } + return FAILURE; +} + +char +front(const Vec8_t* ptr) +{ + if (is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE; + if (ptr->size == 0) return FAILURE; + return at(ptr, 0); +} + +char +back(const Vec8_t* ptr) +{ + if (is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE; + if (ptr->size == 0) return FAILURE; + return at(ptr, ptr->size - 1); +} + +int +empty(const Vec8_t* ptr) +{ + if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) + return FAILURE; + if (ptr->size == 0) return SUCCESS; + return FAILURE; +} + +__attribute__((overloadable)) Vec8_t +erase(const Vec8_t* ptr, const size_t iter) +{ + Vec8_t dst = create(nullptr, 0); + if (is_valid(ptr) == ERR_VECTOR_NULL) return dst; + if (is_valid(ptr) == ERR_BUF_NULL) return dst; + if (iter >= ptr->size) return dst; + dst = *ptr; + memmove(&dst.arr[iter], &dst.arr[iter + 1], + (dst.size - iter - 1) * sizeof(char)); + dst.arr[dst.size - 1] = 0; + dst.size--; + return dst; +} + +__attribute__((overloadable)) Vec8_t +erase(const Vec8_t* ptr, const size_t iter_start, const size_t iter_end) +{ + Vec8_t dst = create(nullptr, 0); + if (is_valid(ptr) == ERR_VECTOR_NULL) return dst; + if (is_valid(ptr) == ERR_BUF_NULL) return dst; + if (iter_end > ptr->size) return dst; + if (iter_start >= iter_end) return dst; + dst = *ptr; + size_t diff = iter_end - iter_start; + memmove(&dst.arr[iter_start], &dst.arr[iter_end], + (dst.size - iter_end) * sizeof(char)); + for (size_t i = dst.size - diff; i < dst.size; i++) + { + dst.arr[i] = 0; + } + dst.size -= diff; + return dst; +} + +__attribute__((overloadable)) Vec8_t +resize(const Vec8_t* ptr, const size_t size) +{ + Vec8_t dst = create(nullptr, 0); + if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) + return dst; + if (ptr->size == size) + { + LOG("ERR :- Ptr size and size are the same"); + dst = *ptr; + return dst; + } + + else if (ptr->size == 0) + { + dst = reserve(&dst, size); + } + + else if (size > ptr->max_size) + { + LOGERROR(ERR_MAX_PASSED); + dst = *ptr; + return dst; + } + else if (size > ptr->capacity) + { + size_t tmp = ptr->capacity; + while (size > tmp) + { + tmp *= 2; + } + dst = reserve(ptr, tmp); + if (!dst.arr) + { + LOGERROR(ERR_BUF_NULL); + dst = *ptr; + return dst; + } + } + if (size < ptr->size) + { + dst = *ptr; + for (size_t i = ptr->size; i > size; i--) + { + dst.arr[i] = '\0'; + } + } + if (ptr->size < size && size <= ptr->capacity) + { + for (size_t i = ptr->size; i < size; i++) + { + dst.arr[i] = '\0'; + } + } + dst.size = size; + return dst; +} + +__attribute__((overloadable)) Vec8_t +resize(Vec8_t* ptr, const size_t size, const char val) +{ + Vec8_t dst = create(nullptr, 0); + dst = *ptr; + if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) + return dst; + + if ((0 < size && size != dst.size && size < dst.size) || + is_valid(ptr) == ERR_SIZE_ZERO) + { + LOGERROR(ERR_SIZE_ZERO); + return dst; + } + if ((0 < size && size < dst.size) || is_valid(ptr) == ERR_SIZE_ZERO) + { + LOGERROR(ERR_SIZE_ZERO); + return dst; + } + if (size >= dst.capacity) + { + dst = reserve(&dst, size); + } + dst.size = ptr->size + (size - ptr->size); + + for (size_t i = ptr->size; i < dst.size; i++) + { + if (at(&dst, i) >= 0) + { + dst.arr[i] = val; + } + } + dst.size = size; + return dst; +} + +__attribute__((overloadable)) Vec8_t +assign(const Vec8_t* ptr, const Vec8_t* iterator, const size_t iter_start, + const size_t iter_end) +{ + Vec8_t dst = create(nullptr, 0); + if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) + return dst; + if (is_valid(iterator) == ERR_VECTOR_NULL || + is_valid(iterator) == ERR_BUF_NULL) + return dst; + + if (ptr->arr == iterator->arr) + { + LOGERROR(ERR_DOUBLE_BUF); + dst = *ptr; + return dst; + } + if (iterator->size < iter_end || iter_end <= iter_start) + { + LOGERROR(ERR_OUT_OF_BOUNDS); + return dst; + } + dst = *ptr; + dst = erase(ptr, begin(ptr), end(ptr) + 1); + dst = reserve(&dst, (iter_end - iter_start)); + for (size_t i = iter_start; i < iter_end; i++) + { + dst = push_back(&dst, at(iterator, i)); + } + return dst; +} + +__attribute__((overloadable)) Vec8_t +assign(const Vec8_t* ptr, const size_t amount, const char val) +{ + Vec8_t dst = create(nullptr, 0); + if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) + return create(nullptr, 0); + dst = *ptr; + if (amount == 0) + { + LOGERROR(ERR_SIZE_ZERO); + return dst; + } + dst = erase(&dst, begin(&dst), end(&dst) + 1); + dst = reserve(&dst, amount); + for (size_t i = 0; i < amount; i++) + { + dst = push_back(&dst, val); + } + return dst; +} + +__attribute__((overloadable)) Vec8_t +insert(const Vec8_t* ptr, const size_t iter, const char val) +{ + Vec8_t dst = create(nullptr, 0); + if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) + { + return dst; + } + if (ptr->max_size < ptr->size + 1) + { + LOGERROR(ERR_MAX_PASSED); + return dst; + } + if (iter > ptr->size) + { + LOGERROR(ERR_OUT_OF_BOUNDS); + return dst; + } + dst = *ptr; + dst = push_back(&dst, 0); + for (size_t i = dst.size - 1; i > iter; i--) + { + dst.arr[i] = dst.arr[i - 1]; + } + dst.arr[iter] = val; + + return dst; +} + +__attribute__((overloadable)) Vec8_t +insert(const Vec8_t* ptr, const size_t iter, const size_t amount, + const char val) +{ + Vec8_t dst = create(nullptr, 0); + if (is_valid(ptr) != SUCCESS) + { + LOGERROR(ERR_NULL); + return dst; + } + if (iter > ptr->size) + { + LOGERROR(ERR_OUT_OF_BOUNDS); + return dst; + } + if (amount <= 0) + { + LOGERROR(ERR_SIZE_ZERO); + return dst; + } + dst = *ptr; + for (size_t i = iter; i < iter + amount; i++) + { + dst = insert(&dst, i, val); + } + return dst; +} + +__attribute__((overloadable)) Vec8_t +insert(const Vec8_t* dst_vec, const Vec8_t* src_vec, const size_t iter, + const size_t iter_start, const size_t iter_end) +{ + Vec8_t dst = create(nullptr, 0); + if (is_valid(dst_vec) != SUCCESS || is_valid(src_vec) != SUCCESS) + { + LOGERROR(ERR_NULL); + return dst; + } + if (iter_end > src_vec->size || iter > dst_vec->size) + { + LOGERROR(ERR_OUT_OF_BOUNDS); + return dst; + } + if (dst_vec->arr == src_vec->arr) + { + LOGERROR(ERR_DOUBLE_BUF); + return dst; + } + dst = *dst_vec; + for (size_t i = iter_start; i < iter_end; i++) + { + dst = insert(&dst, iter + (i - iter_start), src_vec->arr[i]); + } + return dst; +} diff --git a/src/char.c b/src/char.c index 7821264..593b1e4 100644 --- a/src/char.c +++ b/src/char.c @@ -28,9 +28,21 @@ Vec8_t create(const char* buf, const size_t len) { Vec8_t dst = { NULL, 0, CAPACITY, VEC_MAX }; - if (len > dst.capacity) + if (len >= dst.max_size) { - while (len > dst.capacity) dst.capacity *= 2; + LOGERROR(ERR_MAX_PASSED); + LOG("If you need more memory to start, create a blank and " + "reserve."); + return dst; + } + if (dst.capacity < len && len < dst.max_size) + { + while (dst.capacity < len && dst.capacity * 2 < dst.max_size) + dst.capacity *= 2; + } + if (dst.capacity * 2 > dst.max_size && len < dst.max_size) + { + dst.capacity = len; } if (len > 0) { @@ -121,17 +133,11 @@ pop_back(Vec8_t* ptr) return dst; } -/* - * reallocf failure wipes the buffer — push_back (char.c:89-94), reserve - * (char.c:140-147). On alloc failure it frees ptr->arr, then returns arr == - * NULL; caller keeps a dangling pointer. Silent heap corruption. - * - * */ Vec8_t -reserve(const Vec8_t* ptr, const size_t max_size) +reserve(const Vec8_t* ptr, const size_t capacity) { Vec8_t ret = create(nullptr, 0); - if (max_size == 0) + if (capacity == 0) { LOGERROR(ERR_SIZE_ZERO); return ret; @@ -143,11 +149,17 @@ reserve(const Vec8_t* ptr, const size_t max_size) ret.arr = ptr->arr; if (is_valid(&ret) == ERR_BUF_NULL) { - ret.arr = calloc(max_size, sizeof(char)); + ret.arr = calloc(capacity, sizeof(char)); + if (!ret.arr) + { + LOGERROR(ERR_ALLOC_FAIL); + ret = *ptr; + return ret; + } } else if (is_valid(ptr) == SUCCESS) { - ret.arr = realloc(ret.arr, max_size * sizeof(char)); + ret.arr = realloc(ret.arr, capacity * sizeof(char)); if (!ret.arr) { LOGERROR(ERR_ALLOC_FAIL); @@ -155,17 +167,17 @@ reserve(const Vec8_t* ptr, const size_t max_size) return ret; } ret.size = ptr->size; - if (ret.size > max_size) + if (ret.size > capacity) { - for (size_t i = max_size; i < ret.size; i++) + for (size_t i = capacity; i < ret.size; i++) { ret.arr[i] = 0; } - ret.size = max_size; + ret.size = capacity; } } - ret.capacity = max_size; - ret.max_size = max_size; + ret.capacity = capacity; + ret.max_size = capacity; return ret; } @@ -390,6 +402,7 @@ resize(const Vec8_t* ptr, const size_t size) Vec8_t dst = create(nullptr, 0); if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return dst; + dst = *ptr; if (ptr->size == size) { LOG("ERR :- Ptr size and size are the same"); @@ -397,43 +410,62 @@ resize(const Vec8_t* ptr, const size_t size) return dst; } - else if (ptr->size == 0) - { - dst = reserve(&dst, size); - } - else if (size > ptr->max_size) { LOGERROR(ERR_MAX_PASSED); dst = *ptr; return dst; } - else if (size > ptr->capacity) + + else if (ptr->size == 0) { - size_t tmp = ptr->capacity; - while (size > tmp) + size_t max = dst.max_size; + dst = reserve(&dst, size); + if (dst.capacity != size) { - tmp *= 2; - } - dst = reserve(ptr, tmp); - if (!dst.arr) - { - LOGERROR(ERR_BUF_NULL); + LOGERROR(ERR_ALLOC_FAIL); dst = *ptr; return dst; } + for (size_t i = 0; i < size; i++) + { + dst.arr[i] = '\0'; + } + dst.max_size = max; + dst.size = size; + return dst; + } + else if (size > ptr->capacity) + { + size_t tmpcp = ptr->capacity; + size_t tmpmx = ptr->max_size; + while (size > tmpcp) + { + tmpcp *= 2; + } + if (tmpcp > ptr->max_size) + { + tmpcp = size; + } + dst = reserve(ptr, tmpcp); + if (dst.capacity != tmpcp) + { + LOGERROR(ERR_ALLOC_FAIL); + dst = *ptr; + return dst; + } + dst.max_size = tmpmx; } if (size < ptr->size) { - dst = *ptr; - for (size_t i = ptr->size; i > size; i--) + for (size_t i = size; i < dst.size; i++) { dst.arr[i] = '\0'; } } - if (ptr->size < size) + if (dst.size < size && size <= dst.capacity) { - for (size_t i = ptr->size; i < size; i++) + for (size_t i = dst.size; i < size; i++) { dst.arr[i] = '\0'; } @@ -443,33 +475,75 @@ resize(const Vec8_t* ptr, const size_t size) } __attribute__((overloadable)) Vec8_t -resize(Vec8_t* ptr, const size_t size, const char val) +resize(const Vec8_t* ptr, const size_t size, const char val) { Vec8_t dst = create(nullptr, 0); - dst = *ptr; if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return dst; + dst = *ptr; + if (ptr->size == size) + { + LOG("ERR :- Ptr size and size are the same"); + dst = *ptr; + return dst; + } - if ((0 < size && size != dst.size && size < dst.size) || - is_valid(ptr) == ERR_SIZE_ZERO) + else if (size > ptr->max_size) { - LOGERROR(ERR_SIZE_ZERO); + LOGERROR(ERR_MAX_PASSED); + dst = *ptr; return dst; } - if ((0 < size && size < dst.size) || is_valid(ptr) == ERR_SIZE_ZERO) - { - LOGERROR(ERR_SIZE_ZERO); - return dst; - } - if (size >= dst.capacity) + + else if (ptr->size == 0) { + size_t max = dst.max_size; dst = reserve(&dst, size); + if (dst.capacity != size) + { + LOGERROR(ERR_ALLOC_FAIL); + dst = *ptr; + return dst; + } + for (size_t i = 0; i < size; i++) + { + dst.arr[i] = val; + } + dst.max_size = max; + dst.size = size; + return dst; } - dst.size = ptr->size + (size - ptr->size); - - for (size_t i = ptr->size; i < dst.size; i++) + else if (size > ptr->capacity) { - if (at(&dst, i) >= 0) + size_t tmpcp = ptr->capacity; + size_t tmpmx = ptr->max_size; + while (size > tmpcp) + { + tmpcp *= 2; + } + if (tmpcp > ptr->max_size) + { + tmpcp = size; + } + dst = reserve(ptr, tmpcp); + if (dst.capacity != tmpcp) + { + LOGERROR(ERR_ALLOC_FAIL); + dst = *ptr; + return dst; + } + dst.max_size = tmpmx; + } + if (size < ptr->size) + { + for (size_t i = size; i < dst.size; i++) + { + dst.arr[i] = val; + } + } + if (dst.size < size && size <= dst.capacity) + { + for (size_t i = dst.size; i < size; i++) { dst.arr[i] = val; } @@ -488,6 +562,13 @@ assign(const Vec8_t* ptr, const Vec8_t* iterator, const size_t iter_start, if (is_valid(iterator) == ERR_VECTOR_NULL || is_valid(iterator) == ERR_BUF_NULL) return dst; + + if (ptr->arr == iterator->arr) + { + LOGERROR(ERR_DOUBLE_BUF); + dst = *ptr; + return dst; + } if (iterator->size < iter_end || iter_end <= iter_start) { LOGERROR(ERR_OUT_OF_BOUNDS); @@ -510,6 +591,11 @@ assign(const Vec8_t* ptr, const size_t amount, const char val) if (is_valid(ptr) == ERR_VECTOR_NULL || is_valid(ptr) == ERR_BUF_NULL) return create(nullptr, 0); dst = *ptr; + if (amount == 0) + { + LOGERROR(ERR_SIZE_ZERO); + return dst; + } dst = erase(&dst, begin(&dst), end(&dst) + 1); dst = reserve(&dst, amount); for (size_t i = 0; i < amount; i++)