在我的内存管理器系统中,用 C++ 实现了一个内存管理器,其功能包括初始化、跟踪、分配和释放内存部分。当我试图解决我的内存泄漏时(现在 valgrind 报告了 0 个内存泄漏),但我收到了双重释放内存的错误,我不确定为什么。我试过 dgb 但找不到任何特别的东西。
#include "MemoryManager.h"
using namespace std;
MemoryManager::MemoryManager(unsigned wordSize, function<int(int,void *)> allocator){
this->allocator = allocator;
this->word_size = wordSize;
this->node = nullptr;
}
LL_Node::~LL_Node(){
delete next;
}
void MemoryManager::shutdown(){
sbrk(-(size_in_words * word_size));
start = nullptr;
LL_Node* tmp = this->node;
LL_Node* n;
while(tmp) {
n = tmp->next;
delete tmp;
tmp = n;
}
this->node = nullptr;
}
MemoryManager::~MemoryManager(){
shutdown();
}
void MemoryManager::initialize(size_t sizeInwords){
if (sizeInwords < 65536 ) {
this->size_in_words = sizeInwords;
this->mem = word_size * size_in_words;
if (start) {
shutdown();
this->node = nullptr;
}
start = (uint8_t *) sbrk(size_in_words * word_size);
}
}
void* MemoryManager::allocate(size_t sizeInBytes){
if(!this->node){
this->node = new LL_Node(nullptr, nullptr, 0, true, size_in_words);
}
int l = ceil( (float) sizeInBytes/word_size);
int offset = allocator(l, (void*)getList());
if(offset == -1){
return nullptr;
}
LL_Node* temp = this->node;
while (temp && temp->head != offset)
temp = temp->next;
if (temp->size == l) {
temp->hole = false;
}
else {
LL_Node* _node = temp->next;
temp->hole = false;
temp->next = new LL_Node(temp, nullptr,temp->head + l,true,temp->size - l);
if (_node) {
temp->next->next = _node;
delete _node; // delete _node before changing temp->next->next
}
temp->size = l;
}
return this->start + (offset * word_size);
}
void MemoryManager::free(void *address){
int offset = ceil(((uint8_t*) address - this->start) / word_size);
LL_Node* temp = node;
while(temp) {
if(temp->head == offset){
temp->hole = true;
}
temp = temp->next;
}
combine_holes();
}
void MemoryManager::setAllocator(std::function <int(int,void *)> allocator){
this->allocator = allocator;
}
int MemoryManager::dumpMemoryMap(char *filename){
int file = open(filename, O_CREAT|O_WRONLY, 0600);
auto* holeList = static_cast<uint16_t*>(getList());
uint16_t length = *holeList++;
if(file < 0){
return -1;
}
string str;
for(uint16_t i = 0; i < length * 2; i += 2){
if(i==0){
str += "[" + to_string(holeList[i]) + ", " + to_string(holeList[i+1]) + "]";
}
else{
str += " - [" + to_string(holeList[i]) + ", " + to_string(holeList[i+1]) + "]";
}
}
char* buffer = const_cast<char*>(str.c_str());
write(file, buffer, str.length());
close(file);
delete[] this->list;
return 0;
}
void* MemoryManager::getList() {
updateList();
return this->list;
}
void* MemoryManager::getBitmap(){
updateBitmap();
return this->bit_map;
}
unsigned MemoryManager::getWordSize(){
return word_size;
}
void* MemoryManager::getMemoryStart(){
return start;
}
unsigned MemoryManager::getMemoryLimit(){
return mem;
}
void MemoryManager::updateList() {
vector<uint16_t> temp_vec = {};
uint16_t l = 0;
LL_Node *temp = this->node;
uint16_t counter;
while (temp) {
if (temp->hole) {
l++;
temp_vec.push_back(temp->head);
temp_vec.push_back(temp->size);
}
temp = temp->next;
}
auto list_size = (2 * l) + 1;
uint16_t* new_list = new uint16_t[list_size];
new_list[0] = l;
for (counter = 0; counter < l * 2; counter++) {
new_list[counter + 1] = temp_vec[counter];
}
delete[] this->list; // delete previously allocated memory
this->list = new_list;
// Fix: deallocate memory
delete[] new_list;
}
void MemoryManager::combine_holes() {
LL_Node* temp = node;
LL_Node* idk = nullptr;
while (temp != nullptr){
while(temp->hole && temp->next != nullptr && temp->next->hole){
idk = temp->next->next;
temp->size += temp->next->size;
delete temp->next;
temp->next = idk;
}
temp = temp->next;
}
}