How to write custom allocator for vector of pointers?

Hi guys.

I am having this problem that I often use a vector of pointers to some objects.
The problem is that I need to delete pointers in that vector manually which is prone to errors / memory leaks.

Currently I am doing it like this:

1
2
3
4
5
6
7
8
9
10
typedef std::vector<MyObject*> TMyObjects;

void deleteVectors(TMyObjects &MyObjects)
{		
	for (auto i = MyObjects.begin(); i != MyObjects.end(); ++i)
	{
		delete((*i));
	}
	MyObjects.clear();
}


So I would like to get rid of using deleteVectors. I've found two solutions to this problem:

1. I could use Boost library which has pointer containers created for this purpose.
2. I could create a custom allocator which I pass when creating the instance of vector.

I don't want to use the Boost library so I am left up with the solution number 2. The thing is, that my C++ knowledge is yet not good enough to write such allocator by myself. Could someone help me or point me to a code snippet that perfrom this task?

Thank you for your help.
std::vector< std::unique_ptr<MyObject> >
http://en.cppreference.com/w/cpp/memory/unique_ptr
Thank you,

how about the solution based on custom allocator?

Regards.
> how about the solution based on custom allocator?

A standard allocator-aware container would use its allocator for managing storage for the values it holds.

std::vector< MyObject*, my_custom_allocator > would use the allocator to manage storage for holding pointers to MyObject, not for the MyObject instances that these pointers point to.

To illustrate,

1
2
3
4
5
6
7
8
9
std::vector< MyObject*, my_custom_allocator > my_vector ;

my_vector.push_back(nullptr) ;
my_vector.push_back(nullptr) ;

static MyObject my_first_object( /* ... */ ) ;
my_vector[0] = std::addressof(my_first_object) ; // the allocator does not get to know about this

my_vector[1] = new MyObject( /* ... */ ) ; // the allocator does not get to know about this 
Last edited on
Thank you,

so am I wrong thinking that my_custom_allocator is able to call the destructor for the dereferenced pointer? It is not possible to do this?
> am I wrong thinking that my_custom_allocator is able to call the destructor for the dereferenced pointer?

It won't be able to do that (with a dumb pointer) consistently and correctly.

For instance, consider:
1
2
3
4
5
6
7
8
9
10
void foo( std::vector< MyObject*, my_custom_allocator > arg ) // passed by value
{
    // ...
    // arg is destroyed when the function returns; the destructor would ask the allocator to
    // destroy the pointers and deallocate the memory
}

std::vector< MyObject*, my_custom_allocator > my_vector ;
my_vector.push_back( new MyObject( /* ... */ ) ;
foo( my_vector ) ; // pass a copy of my_vector 
Thank you,

I think I understand now. So I've tried to use your suggestion with container of smart pointers but I am having problem when I try to pass object to the vector by initializer list.

Here is an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "stdafx.h"
#include <memory>
#include <vector>

class TMyObject
{
public:
	TMyObject(int ID) : id(ID) {};
	int id;
	TMyObject(TMyObject&& o) {};
	TMyObject(const TMyObject&) = delete;
	TMyObject& operator=(const TMyObject&) = delete;
};

typedef std::unique_ptr<TMyObject> uTMyObject;
typedef std::vector<uTMyObject> TMyObjects;


int main()
{
	//Error	C2280 'std::unique_ptr<TMyObject,std::default_delete<_Ty>>::unique_ptr(const std::unique_ptr<_Ty,std::default_delete<_Ty>> &)': 
	//attempting to reference a deleted function	SmartPointers2015	c : \program files(x86)\microsoft visual studio 14.0\vc\include\xmemory0	737

	TMyObjects lMyObjects({ uTMyObject(new TMyObject(1)) }); 
	return 0;
}


Could you explain me the reason of the error and how to fix it?
Is this because initializer list is creating a temporary vector which then is passed to lMyObjects and it tries to copy elements of this vector which are unique pointers that can't be copied?
std::initializer_list<T> is a proxy for an array of objects.
The vector needs to copy the objects from the underlying array, and std::unique_ptr<> is not copyable (deleted copy constructor)

Something like this perhaps:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class TMyObject
{
public:
	TMyObject(int ID) : id(ID) {};
	int id;
	TMyObject(TMyObject&& o) {};
	TMyObject(const TMyObject&) = delete;
	TMyObject& operator=(const TMyObject&) = delete;
};

int main()
{
    std::vector< std::unique_ptr<TMyObject> > my_objects ;
    my_objects.push_back( std::make_unique<TMyObject>(1) ) ; // move constructed into the vector

    my_objects.push_back( std::unique_ptr<TMyObject>( new TMyObject(2) ) ) ; // clumsy, avoid
                                                              // use std::make_unique instead
}
I see, so there is no way to use initializer list and this makes code very verbose and less readable, that is a shame:(

Thank you for your time.
This is obviously possible:
1
2
3
4
5
6
7
8
9
10
11
std::vector< std::unique_ptr<TMyObject> > make_vector( std::initializer_list<int> ilist )
{
    std::vector< std::unique_ptr<TMyObject> > vec ;
    for( auto i : ilist ) vec.push_back( std::make_unique<TMyObject>(i) ) ;
    return vec ;
}

int main()
{
    auto my_objects = make_vector( { 23, 67, 2, 55, 96, 68, 42 } ) ;
}
Thank you,

that is exactly what I needed:)
Topic archived. No new replies allowed.