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);
Niklas R
  • 16,299
  • 28
  • 108
  • 203

4 Answers4

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
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • 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. – Niklas R May 01 '13 at 11:29
  • 1
    @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. – Joseph Mansfield May 01 '13 at 11:33
  • @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. – Joseph Mansfield May 01 '13 at 11:54
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.

john
  • 7,897
  • 29
  • 27
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();
slow
  • 31
  • 2
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?

codah
  • 466
  • 4
  • 14
  • This is not a useful answer. Yes, I have determined that it actually *is* an issue. Any overhead should be reduced, if possible. – Niklas R May 01 '13 at 11:22
  • 3
    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. – codah May 01 '13 at 20:58