1

I am facing some problems for using placement new for contiguous memory.Please guide me, if there is any other way to do this.
Please refer my code.

#include <new>  
//================================================
class MyClass
{
 private:
    int ma;
 public:
    MyClass():ma(-1){}      
};
//===========================================

int main()
{
    // I am allocating the memory for holding 10 elements of MyClass on heap
    void* pMyClass = ::operator new(sizeof(MyClass)*10);

    //! Note :: the address of pMyClass1 and pMyClass will now point to same   
    //location after calling placement new  

    MyClass* pMyClass1 = :: new(pMyClass)MyClass();  

    //! Problem with this is that, 
    //! i can only instantiate the constructor for the  base address. That is 
    //!  pMyClass[0]. 
    //! If i have to instantiate it for all the other instances, 
    //! that is pMyClass[1] to pMyClass[9], then how to do it ?
    return 0;
}
Luca Martini
  • 1,434
  • 1
  • 15
  • 35
Atul
  • 745
  • 3
  • 9
  • 17

3 Answers3

1

You have the beginning of the memory in pMyClass, and the stride is sizeof(MyClass). So, what you need to do is for example:

MyClass* pMyClass2 = ::new((MyClass*)pMyClass + 1)MyClass();
Ylisar
  • 4,293
  • 21
  • 27
  • Or `new (pMyClass + sizeof(MyClass)) MyClass()`. Or just cheat, and declare `MyClass* pMyClass`, casting the return of the `::operator new` function. – James Kanze Mar 26 '12 at 12:43
0

You have to call the placement new inside a loop that iterates on the 10 contiguous chunks of memory:

int main()
{
    void* pMyClass = ::operator new(sizeof(MyClass)*10);
    MyClass* pMyClass1 = reinterpret_cast<MyClass*>(pMyClass);
    for (size_t i=0; i<10; ++i) {
        ::new(pMyClass1++)MyClass();
    }
    // ... 
}
Luca Martini
  • 1,434
  • 1
  • 15
  • 35
  • 2
    @Atul if you don't know loops, you shouldn't be using placement new yet. I recommend you grab [a good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – R. Martinho Fernandes Mar 26 '12 at 11:02
0

Try:

MyClass* pMyClass1 = :: new(pMyClass)MyClass[10];   
  • You should also reserve some extra memory for compiler which stores array size (to provide correct delete[]); so the allocation should be void* pMyClass = ::operator new(sizeof(MyClass)*10+ extra). For practical purpose extra=sizeof(uint64_t) is usially sufficient; howevere, I don't know standard-compliant way to calculate the extra value – user396672 Mar 26 '12 at 11:05
  • @user396672 There is no way to know the value you need for `extra`. That's what R, Martiho Fernandes means by saying that it's broken. 1024 is "usually sufficient", too, but it's no more guaranteed than `sizeof(uint64_t)`. – James Kanze Mar 26 '12 at 12:46
  • What's the point? If he wanted to initialize all in one go, then `new MyClass[10]` does the trick. About the only time you'd want to do something like what he's doing is for things like vector, where you allocate for n objects, but construct for one at a time, lazily. – James Kanze Mar 26 '12 at 12:48