Я реализовал ByteBuffer (в основном динамический массив байтов c), используя mimallo c.
Вот источник.
ByteBuffer.h
/*****************************************************************
* Arturo :VM
*
* Programming Language + Compiler
* (c) 2019 Yanis Zafirópulos (aka Dr.Kameleon)
*
* @file: src/core/bytebuffer.h
*****************************************************************/
#ifndef __BYTEBUFFER_H__
#define __BYTEBUFFER_H__
/**************************************
Type definitions
**************************************/
typedef uint8_t Byte;
typedef uint16_t Word;
typedef uint32_t Dword;
typedef uint64_t Value;
typedef struct {
size_t size;
size_t capacity;
Byte *data;
} ByteBuffer;
/**************************************
Methods
**************************************/
ByteBuffer* newByteBuffer(size_t size);
void inline resizeByteBuffer(ByteBuffer* buff);
void writeByte(ByteBuffer* buff, Byte b);
void rewriteByte(ByteBuffer* buff, Byte b);
Byte readByte(ByteBuffer* buff, int pos);
void writeWord(ByteBuffer* buff, Word w);
Word readWord(ByteBuffer* buff, int pos);
void writeDword(ByteBuffer* buff, Dword d);
Dword readDword(ByteBuffer* buff, int pos);
void writeValue(ByteBuffer* buff, Value v);
Value readValue(ByteBuffer* buff, int pos);
void freeByteBuffer(ByteBuffer* buff);
#endif
ByteBuffer. c
/*****************************************************************
* Arturo :VM
*
* Programming Language + Compiler
* (c) 2019 Yanis Zafirópulos (aka Dr.Kameleon)
*
* @file: src/core/bytebuffer.c
*****************************************************************/
#include "arturo.h"
/**************************************
Costructors
**************************************/
ByteBuffer* newByteBuffer(size_t size) {
ByteBuffer *p = malloc(sizeof(ByteBuffer));
p->size = size;
p->capacity = size;
if(size) {
p->data = calloc(size, sizeof(Byte));
} else {
p->data = NULL;
}
return p;
}
/**************************************
Resizing
**************************************/
void inline resizeByteBuffer(ByteBuffer* buff) {
buff->capacity = 2 * buff->size;
buff->data = realloc(buff->data, buff->capacity * sizeof(Byte));
}
/**************************************
Methods
**************************************/
void writeByte(ByteBuffer* buff, Byte b) {
buff->size++;
if (buff->size >= buff->capacity) resizeByteBuffer(buff);
buff->data[buff->size - 1] = b;
}
void rewriteByte(ByteBuffer* buff, Byte b) {
buff->data[buff->size - 1] = b;
}
Byte readByte(ByteBuffer* buff, int pos) {
return (Byte)(buff->data[pos]);
}
void writeWord(ByteBuffer* buff, Word w) {
buff->size += 2;
if (buff->size >= buff->capacity) resizeByteBuffer(buff);
buff->data[buff->size - 2] = (Byte)(w >> 8);
buff->data[buff->size - 1] = (Byte)(w);
}
Word readWord(ByteBuffer* buff, int pos) {
return (Word)buff->data[pos] << 8 |
(Word)buff->data[pos+1];
}
void writeDword(ByteBuffer* buff, Dword d) {
buff->size += 4;
if (buff->size >= buff->capacity) resizeByteBuffer(buff);
buff->data[buff->size - 4] = (Byte)(d >> 24);
buff->data[buff->size - 3] = (Byte)(d >> 16);
buff->data[buff->size - 2] = (Byte)(d >> 8);
buff->data[buff->size - 1] = (Byte)(d);
}
Dword readDword(ByteBuffer* buff, int pos) {
return (Dword)buff->data[pos] << 24 |
(Dword)buff->data[pos+1] << 16 |
(Dword)buff->data[pos+2] << 8 |
(Dword)buff->data[pos+3];
}
void writeValue(ByteBuffer* buff, Value v) {
buff->size += 8;
if (buff->size >= buff->capacity) resizeByteBuffer(buff);
buff->data[buff->size - 8] = (Byte)(v >> 56);
buff->data[buff->size - 7] = (Byte)(v >> 48);
buff->data[buff->size - 6] = (Byte)(v >> 40);
buff->data[buff->size - 5] = (Byte)(v >> 32);
buff->data[buff->size - 4] = (Byte)(v >> 24);
buff->data[buff->size - 3] = (Byte)(v >> 16);
buff->data[buff->size - 2] = (Byte)(v >> 8);
buff->data[buff->size - 1] = (Byte)(v);
}
Value readValue(ByteBuffer* buff, int pos) {
return (Value)buff->data[pos] << 56 |
(Value)buff->data[pos+1] << 48 |
(Value)buff->data[pos+2] << 40 |
(Value)buff->data[pos+3] << 32 |
(Value)buff->data[pos+4] << 24 |
(Value)buff->data[pos+5] << 16 |
(Value)buff->data[pos+6] << 8 |
(Value)buff->data[pos+7];
}
/**************************************
Destructors
**************************************/
void freeByteBuffer(ByteBuffer* buff) {
free(buff->data);
free(buff);
}
Тем не менее, при использовании mimallo c используется профилирование, статистика и если мы проведем сравнительный анализ, это покажет, что часть памяти не была освобождена:
Видите ли вы что-то не так с моим кодом?
ОБНОВЛЕНИЕ: Пример кода вызова (рассматриваемый тест):
ByteBuffer* bb = newByteBuffer(0);
double start = getCurrentTime();
for (int i=0; i<100000000; i++) {
writeByte(bb,(Byte)i);
}
printf("total time (bb): %g\n",getCurrentTime()-start);
freeByteBuffer(bb);