0

Can we place dynamically allocated objects at some other place than heap?? How will I define an overloaded new operator for that??

If I have some class Arena like

 class Arena{
      char area[2000];
 public:
      Arena(){}
 };

Arena my_arena(1000);

And I want to allocate objects from Arena my_arena..

Further, what are the possible drawbacks in such memory allocation as compared to allocation from the heap on the performance etc??

trincot
  • 317,000
  • 35
  • 244
  • 286
bhuwansahni
  • 1,834
  • 1
  • 14
  • 20
  • I want heap to be of a particular size.. – bhuwansahni Mar 15 '12 at 08:12
  • 3
    [placement new()](http://stackoverflow.com/questions/222557/cs-placement-new). – iammilind Mar 15 '12 at 08:14
  • For the standard library containers you can implement your own [allocator](http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4079). For other uses, you have to override the [`new`](http://en.cppreference.com/w/cpp/memory/new/operator_new) operator. – Some programmer dude Mar 15 '12 at 08:16
  • @JoachimPileborg The standard already contains the necessary overload of `new` (and you want an overload, not an override). – James Kanze Mar 15 '12 at 08:37
  • Google for "c++ placement new". There is some flexibility in the C++ `new` and `delete` for this. Lots of hits. Here is one: http://en.wikipedia.org/wiki/Placement_syntax Quite a bit of information there, including some examples with custom allocation. – Kaz Mar 15 '12 at 08:13

3 Answers3

5

You can easily use placement new for this:

MyClass* p = new (area) MyClass;

There are two issues you have to be aware of, however:

  1. There is no guarantee that `area` will be correctly aligned for `MyClass`. I usually solve this by means of a union:
        union
        {
            double dummyForAlignment;
            //  Any other types which might be necessary...
            unsigned char area[2000];
        };
    
    This is very ad hoc; there's no formal guarantee as to what types you have to add to be sure. In practice, instead of `double`, I use a union of most of the basic types, plus a couple of pointers, just to be sure.
  2. Because you've used new, the compiler won't take care of destruction for you, as it would for a normal data member. You'll have to call the destructor explicitly:
        p->~MyClass();
    
    Which means that you'll have to keep track of how many objects of what types, and where, have been allocated.

The drawbacks of this technique are the two points I've just mentionned. Plus, unless you keep a typed pointer to the constructed objects, you may have problems viewing them in a debugger. Still, it's a useful technique for some specific uses: I use it in my Fallible class, in order to avoid the need of default constructor; the standard containers require it, and of course, pre-standard vector or array classes generally used it as well. It's also useful for various variant classes; I presume it is used in boost::variant, for example.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • What's with edits that change the meaning of my posting. I have no problem with people correcting my spelling (I'm a bad speller), there was an edit which added a word which didn't belong, and made the answer less accurate. (I've reverted the edit with an edit of my own.) – James Kanze Mar 15 '12 at 09:26
1

It is possible, but rather low-level.

James adequately covered the C++03 do it yourself code, so let me present alternatives.

First, in C++03 you have two alternatives with Boost:

  • Boost.Optional: boost::optional<MyClass> which as the name implies allows you to have (or not) an instance of the type.
  • Boost.Variant: boost::variant<SomeClass,OtherClass,YetAnotherClass> which is a kind of union with type safe semantics and guaranteed constructors/destructors calls.

Second, in C++11 was introduced std::aligned_storage<Len,Align> which takes two parameters:

  • the number of bytes of storage required
  • the alignment required

It uses dark compiler magic to guarantee that the alignment is satisfied, so it is a good basis for building raw-memory manipulation routines.

Personally I would opt for boost::optional in your case:

boost::optional<MyClass> Arena[256];

this models exactly what you want because by default boost::optional is instantiated empty.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722
0

You can simply make overloading operator new&delete and declare the variables/class on stack.

Or, you probably want to use some kind of static pool so you can statically manage them.

Tim Post
  • 33,371
  • 15
  • 110
  • 174