【问题标题】:What is the purpose of the second parameter to std::allocator<T>::deallocate?std::allocator<T>::deallocate 的第二个参数的目的是什么?
【发布时间】:2010-09-08 19:26:48
【问题描述】:

In here 是 deallocate mem 的声明。分配器类。我的问题是这个声明中的第二个论点是什么?如果此函数调用 operator delete(_Ptr),则此参数未使用,那么它有什么用?
谢谢。

摘自 MSDN:

从指定位置开始的存储中释放指定数量的对象。

void deallocate(
   pointer _Ptr, 
   size_type _Count
);  

参数

_Ptr 指向要从存储中释放的第一个对象的指针。

_计数 要从存储中释放的对象数。

【问题讨论】:

  • 您能引用该链接的至少一部分吗?如果该特定 MSDN 参考移动或消失或暂时不可用,则问题将难以理解。 (我之前遇到过损坏的 MSDN 链接。)

标签: c++ pointers memory-management


【解决方案1】:

当您调用deallocate 时,您必须给它一个您之前通过调用allocate 获得的指针,以及您在最初分配内存时传递给allocate 的大小。

例如,

#include <memory>

std::allocator<int> a;
int* p = a.allocate(42);
a.deallocate(p, 42);     // the size must match the size passed to allocate

这对于许多不同类型的分配器很有用。例如,您可能有一个分配器,它为不同大小的块使用不同的池;这样的分配器需要知道要释放的块的大小,以便知道需要将内存返回到哪个池。

【讨论】:

  • @A-ha:这取决于分配器在后台做什么。在默认分配器 (std::allocator&lt;T&gt;) 的情况下,大小被忽略,deallocate 函数只执行::operator delete(p);。其他分配器的行为可能不同。
  • @James 那么例如我如何释放字节数?我应该使用什么结构?我的意思是实现会是什么样子?
  • @A-ha:你什么意思?您需要使用std::allocator&lt;char&gt;,分配count 字节,然后调用deallocate 来释放该内存。
  • @James 但是如果我使用 allocate(count) 那么我可以在不指定字节数的情况下使用 deallocate(where) 那么这样做有什么意义呢?
  • @A-ha:std::allocator 只是默认分配器;它还定义了其他分配器需要遵循的接口,以便标准库容器可以使用。默认分配器不使用该大小。它其他分配器实现(例如,池分配器)使用。
【解决方案2】:

它没有被使用。

来自MSDN

释放指定数量的对象 从存储开始于指定 位置(在本例中为 _Ptr)。

参数

_Ptr 指向要从存储中释放的第一个对象的指针。 (起始位置)

_Count 要从存储中释放的对象数。

Sample code:

// allocator_allocate.cpp
// compile with: /EHsc
#include <memory>
#include <iostream>
#include <vector>

using namespace std;

int main( ) 
{
   allocator<int> v1Alloc;

   allocator<int>::pointer v1aPtr;

   v1aPtr = v1Alloc.allocate ( 10 );

   int i;
   for ( i = 0 ; i < 10 ; i++ )
   {
      v1aPtr[ i ] = i;
   }

   for ( i = 0 ; i < 10 ; i++ )
   {
      cout << v1aPtr[ i ] << " ";
   }
   cout << endl;

   v1Alloc.deallocate( v1aPtr, 10 );
}

【讨论】:

  • 但不应该释放内存(在这种情况下不需要第二个参数)而不调用对象的 dtors?我认为破坏是为了这个目的。
  • 是的,它就是这样做的。它会释放内存,但它会更进一步,在这种情况下只允许释放一部分内存。
  • 如果您要引用第三方来源的文本或代码,请注明来源,以便人们知道它来自哪里。
  • @James McNellis:刚刚添加了来源。有时我忘记添加来源。我尽量做到这一点。感谢您的评论。
  • 这个答案仍然是错误的(或者至少令人困惑),但是:对于默认分配器 (std::allocator&lt;T&gt;),大小参数 未使用。
【解决方案3】:

(参考分配器文档中的示例:http://msdn.microsoft.com/en-us/library/723te7k3.aspx

我假设分配器不执行 new[] 并且不保留已分配元素的数量,因此它不能执行 delete[] ?

所以用户需要告诉分配多少和释放多少。

M.

【讨论】:

    【解决方案4】:

    在我看来,它期望 _Ptr 是指向对象数组的指针,并且它基本上是在做:

    for (size_type i = 0; i<_Count; i++) {
        delete _Ptr;
        _Ptr++;
    }
    

    【讨论】:

    • 没有。该指针必须是从先前调用allocate 获得的指针,并且大小必须是在获得该指针时传递给allocate 的大小。
    • 你是否按照你的建议使用_Ptrnew type[size] 然后你不能像你说的那样删除它,你必须使用delete []
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-29
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    相关资源
    最近更新 更多