views:

152

answers:

4

In here is declaration of deallocate mem. of allocator class. My question is what for is second argument in this declaration? If this function calls operator delete(_Ptr) this argument is unused so what's for is it there?
Thanks.

Excerpt from MSDN:

Frees a specified number of objects from storage beginning at a specified position.

void deallocate(
   pointer _Ptr, 
   size_type _Count
);  

Parameters

_Ptr A pointer to the first object to be deallocated from storage.

_Count The number of objects to be deallocated from storage.

+4  A: 

It's not unused.

From MSDN:

Frees a specified number of objects from storage beginning at a specified position (_Ptr in this case).

Parameters

_Ptr A pointer to the first object to be deallocated from storage. (start position)

_Count The number of objects to be deallocated from storage.

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 );
}
Leniel Macaferi
@Leniel but shoudn't deallocate just frees memory (and in that case do not need second parameter) without calling dtors of objects? I thought destroy is for that purpouse.
There is nothing we can do
Yes, that's what it does. It deallocates memory but it goes further and allows you to deallocate only a portion of the memory in this case.
Leniel Macaferi
If you are going to quote text or code from a third party source, please cite the source so that people know where it is from.
James McNellis
@James McNellis: just added the source. Sometimes I forget to add the source. I try to do this as much as possible. Thanks for the comment.
Leniel Macaferi
This answer is still wrong (or at least confusing), though: for the default allocator (`std::allocator<T>`), the size parameter _is_ unused.
James McNellis
A: 

(reference the example in the documentation for the allocator : http://msdn.microsoft.com/en-us/library/723te7k3.aspx)

I assume that the allocator does not do a new[] and does not keep the number of allocated elements so it cannot do a delete[] ?

so the user need to tell how many to allocate and how many to deallocate.

M.

Max
A: 

It appears to me that it's expecting _Ptr to be a pointer into an array of objects, and that it's basically doing:

for (size_type i = 0; i<_Count; i++) {
    delete _Ptr;
    _Ptr++;
}
ngroot
No. The pointer must be a pointer obtained from a previous call to `allocate`, and the size must be the size that was passed to `allocate` when that pointer was obtained.
James McNellis
And is you do what you suggest with a `_Ptr` to was a `new type[size]` then you cannot delete it like you say, you have to use `delete []`.
Cedric H.
+5  A: 

When you call deallocate, you must give it a pointer that you previously obtained from calling allocate and the size that you passed to allocate when you initially allocated the memory.

For example,

#include <memory>

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

This is useful for many different types of allocators. For example, you may have an allocator that uses different pools for blocks of different sizes; such an allocator would need to know what the size of the block being deallocated is so that it knows to which pool it needs to return the memory.

James McNellis
@A-ha: It depends on what the allocator is doing under the hood. In the case of the default allocator (`std::allocator<T>`), the size is ignored and the `deallocate` function simply performs `::operator delete(p);`. Other allocators may behave differently.
James McNellis
@James so how for example I could deallocate count of bytes? What consturct shall I use? I mean how would the implementation looked like?
There is nothing we can do
@A-ha: What do you mean? You would need to use an `std::allocator<char>`, allocate `count` bytes, then call `deallocate` to deallocate that memory.
James McNellis
@James but if I use allocate(count) then I can use deallocate(where) without specifying byte count so what's the point in doing so?
There is nothing we can do
@A-ha: I don't understand what you are asking. `deallocate` is not an overloaded function: it takes exactly two arguments: a pointer that was previously obtained from a call to `allocate`, and the value passed to `allocate` when that pointer was obtained. You can't deallocate just a piece of an allocation.
James McNellis
@James here:http://msdn.microsoft.com/en-us/library/5t5fykhz(v=VS.71).aspx there is a description of how it is implemented and there in the code the size argument isn't mention anywhere so what for is it? If for example I allocate with ::operator new (sizeof(T)*count) then I can easily deallocate this region of memory by simply calling ::operator delete(ptr_from_allocate). So I do not need size argument for this second call. So when do I use it? Thanks for patience.
There is nothing we can do
@A-ha: The `std::allocator` is just the default allocator; it also defines the interface that other allocators need to follow in order to be usable by the standard library containers. The size is not used by the default allocator. It _is_ used by other allocator implementations (e.g., pool allocators).
James McNellis