#pragma once #include <stdlib.h> #include <stdio.h> #include <malloc.h> #include <string.h> #include <assert.h> #include <iostream> using namespace std; class CharVector { public: CharVector(): base_ptr(nullptr), len(0), cap(0) { reserve(64); } CharVector(size_t n) : base_ptr(nullptr), len(0), cap(0) { reserve(n); } ~CharVector() { if (base_ptr) free(base_ptr); } char * data() { return base_ptr; } size_t size() { return len; } size_t capacity() { return cap; } bool push_back(char ch) { if (len < cap) { base_ptr[len] = ch; len++; return true; } else { size_t sz = cap; if (cap > 10 * 1024 * 1024) // 10MB { sz = cap + 1024 * 1024; } else { sz = cap * 2; } bool ret = reserve(sz); if (ret == false) return false; base_ptr[len] = ch; len++; return true; } } void clear() { len = 0; } bool reserve(size_t n) { bool ret = allocMem(n); //cout <<" reserve : "<< size() << "," << capacity() << endl; return ret; } private: inline bool allocMem(size_t n) { if (base_ptr == nullptr) { base_ptr = (char *)malloc(n); if (base_ptr == nullptr) return false; cap = n; return true; } if (n > cap) { void *new_ptr = realloc(base_ptr, n); if (new_ptr == nullptr) { new_ptr = malloc(n); if (new_ptr == nullptr) return false; memcpy(new_ptr, base_ptr, len); cap = n; free(base_ptr); base_ptr = (char *)new_ptr; return true; } else { cap = n; if (base_ptr != new_ptr) // { //must not call free(base_ptr), because realloc has done!!! base_ptr = (char *)new_ptr; } return true; } } // n < cap, don't do anything return true; } private: char * base_ptr; size_t len; size_t cap; };
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter