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

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

我试图用C ++为一个类编写一个内存分配器,由于某种原因,当程序试图释放它们时,我分配的块无法正确保存其数据。

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

程序还可以通过将内存块重新插入列表并查找其“伙伴”(拆分其父对象时创建的另一个块)来尝试合并它们,以释放它们,从而释放它们。它可以。它通过检查块的内存地址来实现。

由于分配和免费通话之间的某种原因,我的内存块被更改了,我不确定为什么。

alloc():

`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

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

我的代码看起来不错,并通过简单的测试(分配一个,释放相同的一个,就是这样),它可以工作,但是当我尝试自动分配/释放块时,我无法弄清楚为什么它不起作用。谁能帮忙?

c++ memory-management dynamic-memory-allocation
1个回答
2
投票

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

简单的“分配,然后免费”将起作用。问题是您是否使用分配器的返回值。

类似地,免费,您需要从其中的void *查找BlockHeader。通常,您可以通过减去字段偏移量或sizeof(BlockHeader)

来执行此操作
© www.soinside.com 2019 - 2024. All rights reserved.