Утечка памяти при использовании mimallo c - PullRequest
1 голос
/ 07 января 2020

Я реализовал 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 используется профилирование, статистика и если мы проведем сравнительный анализ, это покажет, что часть памяти не была освобождена:

enter image description here


Видите ли вы что-то не так с моим кодом?


ОБНОВЛЕНИЕ: Пример кода вызова (рассматриваемый тест):

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);
...