C++ uninitialized array of class instances
Asked Answered
S

4

7

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);
Sunbonnet answered 1/5, 2013 at 10:16 Comment(0)
D
7

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
Dusty answered 1/5, 2013 at 10:19 Comment(3)
Thanks for your answer. Any disadvantages of using a C style cast over static_cast? The construction syntax was new to me. Speed is the key, I don't think a map suits since I really need a linear array of a fixed number of elements.Sunbonnet
@Niklas In this case, no there is no disadvantage. The C style cast is defined as the first of a set of casts that will succeed. In this case, it will be equivalent to a static_cast. However, I prefer to be explicit. Also, there is plenty of information on Stack Overflow about the placement new syntax.Dusty
@NiklasR Just to make sure: do you want to create objects sequentially (starting from index 0 and up) or at arbitrary positions within the array? If you want them sequentially, then slow's std::vector answer is appropriate.Dusty
M
4

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.

Mussolini answered 1/5, 2013 at 10:18 Comment(0)
H
3

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();
Haemostasis answered 1/5, 2013 at 10:45 Comment(0)
V
0

Have you timed it? Does it take 'too long'? Does this occur only once in the execution of your program, like at the start? First determine that it is actually an issue.

Do you really need to allocate the 1000 objects in this way?

Apart from that, if the constructors don't get called, how are the objects going to be... constructed?

Valorous answered 1/5, 2013 at 10:45 Comment(2)
This is not a useful answer. Yes, I have determined that it actually is an issue. Any overhead should be reduced, if possible.Sunbonnet
No problem. It wasn't raised by other commenters and you didn't mention that in your question, so I thought it was a relevant angle. Now I see sftrabbit has asked "I wonder whether you really want to be doing this dynamic allocation yourself" which is similar to my 2nd comment.Valorous

© 2022 - 2024 — McMap. All rights reserved.