Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ uninitialized array of class instances

I've been searching but couldn't find an answer to this. Is there a way to tell the new operator to not call the class constructors?

MyObject* array = new MyObject[1000];

This will call MyObject() a thousand times! I want to fill the allocated memory myself and do not need any information initialized in the constructor. Using malloc() is not very harmonic C++ code imho.

MyObject* array = (MyObject*) malloc(sizeof(MyObject) * 1000);
like image 886
Niklas R Avatar asked May 01 '13 10:05

Niklas R


3 Answers

The C++ equivalent to malloc is the allocation function operator new. You can use it like so:

MyObject* array = static_cast<MyObject*>(::operator new(sizeof(MyObject) * 1000));

You can then construct a particular object with placement new:

new (array + 0) MyObject();

Replace 0 with whichever offset you wish to initialise.

However, I wonder whether you really want to be doing this dynamic allocation yourself. Perhaps a std::map<int, MyObject> or std::unordered_map<int, MyObject> would suit you better, so that you can create a MyObject at any index.

std::unordered_map<int, MyObject> m;
m[100]; // Default construct MyObject with key 100
like image 91
Joseph Mansfield Avatar answered Oct 26 '22 09:10

Joseph Mansfield


Indeed, using malloc is not very harmonic with C++ code. But malloc does exactly what you are asking for. So I'm afraid what you are asking for is not very harmonic with C++ either. I guess you've just got to decide what language you'd rather program in C or C++.

I suppose your only other real option is to rewrite MyObject so it does not have any constructors, but that not really the C++ way either.

like image 33
john Avatar answered Oct 26 '22 11:10

john


just use std::vector

std::vector<MyObject> v;

v.reserve(1000); // allocate raw memory
v.emplace_back(42); // construct in place

for random access (this is (basically) what std::vector does internally):

typedef std::aligned_storage<sizeof(MyObject), std::alignment_of<MyObject>::value>::type Storage;
MyObject* myObjects(reinterpret_cast<MyObject*>(new Storage[1000]));

new (myObjects + 42) MyObject(/* ? */); // placement new
(*(myObjects + 42)).~MyObject();
like image 35
slow Avatar answered Oct 26 '22 10:10

slow