c++ - 为什么我分配的内存块不一致?

标签 c++ memory-management dynamic-memory-allocation

我试图在 C++ 中为一个类编写一个内存分配器,由于某种原因,当程序试图释放它们时,我分配的 block 没有正确保存它们的数据。

基本上有一个包含不同大小内存块的列表 vector 。当请求一部分内存时,会找到一个合适的 block 并将其返回给用户。如果在其中一个列表中找不到合适的 block ,但有一个更大的 block ,则从列表中删除较大的 block ,分成两半,然后将这两个 block 插入到下面的级别中。

该程序还可以通过将内存块重新插入到列表中并寻找它的“伙伴”(当其父 block 被拆分时创建的 block )来尝试合并它们,只要它可以递归地执行它就可以释放内存块.它通过检查 block 的内存地址来做到这一点。

由于分配和空闲调用之间的某种原因,我的内存块正在被更改,我不确定为什么。

分配():

`void *BuddyAllocator::alloc(int length)
{
  cout << "Block size " << length << " requested" << endl;
  int rounded_length = round_up(length);
  if (rounded_length <= available_mem)
  {
    cout << "Searching for block size " << rounded_length << endl;
    bool loop = true;
    while (loop)
    {
      for (int i = 0; i <= FreeList.size(); i++)
      {
        if (FreeList[i].head != nullptr)
        {
          BlockHeader *iter = FreeList[i].head;
          if (iter->block_size == rounded_length && iter->free)
          {
            cout << "Suitable block found, returning block "<<iter<<" size: " << iter->block_size << endl;
            loop = false;
            FreeList[i].remove(iter);
            available_mem -= iter->block_size;
            return (void *)iter;
          }
          else if (iter->block_size > rounded_length && iter->free)
          {
            cout << "Large block found, splitting block size: " << iter->block_size << endl;
            split(iter);
            break;
          }
        }
      }
    }
  }
  else
  {
    cout << "Not enough memory available" << endl;
  }
  return nullptr;
}`
split: `void *BuddyAllocator::split(BlockHeader *block)
{
  int level = log2((double)block->block_size / basic_block_size);
  BlockHeader *left = block;
  int child_size = block->block_size / 2;
  left->block_size = child_size;
  BlockHeader *right = new ((char *)block + left->block_size) BlockHeader(child_size, true);
  FreeList[level].remove(block);
  FreeList[level - 1].insert(right);
  cout << "inserting right block into level: " << level - 1 << " size: " << child_size << endl;
  FreeList[level - 1].insert(left);
  cout << "inserting left block into level: " << level - 1 << " size: " << child_size << endl;
}`

自由():
`void BuddyAllocator::free(void *a)
{
  BlockHeader *to_free = (BlockHeader *)a;
  int level = log2((double)to_free->block_size / basic_block_size); //find level to insert block into
  FreeList[level].insert(to_free);
  BlockHeader *iter = to_free->next;
  cout << "Freeing memory: " << to_free << endl
       << "Block size: " << to_free->block_size << endl;

  while (1 == 1)
  {
    if (((char *)iter == ((char *)to_free + to_free->block_size))) //check addresses to check for match
    {
      cout << "Joining segments" << endl;
      BlockHeader *joined_block = new ((char *)to_free) BlockHeader(to_free->block_size * 2, true);
      joined_block->next = nullptr;
      FreeList[level].remove(iter);
      FreeList[level].remove(to_free);
      free(joined_block);
      break;
    }
    else if ((char *)iter == ((char *)to_free - to_free->block_size)) //check addresses to check for match
    {
      cout << "Joining segments" << endl;
      BlockHeader *joined_block = new ((char *)iter) BlockHeader(to_free->block_size * 2, true);
      joined_block->next = nullptr;
      FreeList[level].remove(iter);
      FreeList[level].remove(to_free);
      free(joined_block);
      break;
    }
    else if (iter != nullptr)
    {
      iter = iter->next;
    }
    else
    {
      cout << "Buddy not found :(" << endl;
      break;
    }
  }
}`

这是我遇到的错误:
enter image description here

您可以看到,当分配 block 0x7...a410 时,它正确显示该 block 的大小为 1024,但是当我尝试释放相同的地址时,它显示大小为 111138594(真的错了)。它并不总是发生,正如您所看到的,当 block 0x7...a210 在分配和释放时都显示大小为 128。

我的代码看起来不错,并且通过简单的测试(分配一个,释放同一个,仅此而已)它可以工作,但是当我尝试自动分配/释放 block 时,我无法弄清楚为什么它不起作用。任何人都可以帮忙吗?

最佳答案

分配器通常不返回数据结构节点(在您的情况下为 BlockHeader)。他们将其中的空白区域返回为 void * .如果您的调用者将数据存储在分配器的返回值中,他们将覆盖其字段。

简单的“分配,然后释放”就可以了。问题是如果你使用分配器的返回。

同样,免费时,您需要从 void * 中找到 BlockHeader在其中。通常通过减去字段偏移量或 sizeof(BlockHeader) 来实现。

关于c++ - 为什么我分配的内存块不一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60106058/

相关文章:

c++ - 将浮点值从 Objective-C 传递到 C++ 方法

c++ - 使用 size_t 声明最大数组

iphone - 当我的应用收到内存警告时该怎么办?

ios - 我需要在异步函数中释放参数吗?

Java8 已完全从其内存区域中删除了永久代空间。它会完全阻止内存泄漏问题吗? ...

c++ - C 和 C++ 中的堆数组对齐以简化编译器 (GCC) 向量化

c++ - 如何在多维数组中输入值?

android - setContentSize 在 cocos2dx3.0 中不起作用

c - Realloc() 行为

c - 填充动态字符数组会导致覆盖