不确定我为什么以及在哪里收到免费():在 tcache 2 中检测到双重免费

问题描述 投票:0回答:0

在我的内存管理器系统中,用 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;
   }
}
c++ memory-management double-free
© www.soinside.com 2019 - 2024. All rights reserved.