2

Started experimenting with placement new and delete along with memory alignment and it feels like being brainy smurf in papas smurf's lab.

Lets say I have an object e.g.,

struct obj {
...
};

and I want to allocate in aligned storage an array with N such objects. What I do is:

obj *buf = new (static_cast<obj*>(_aligned_malloc(sizeof(obj) * N, 64))) obj[N];

That is, I use placement new in combination with _aligned_malloc.

Q

  • Is this way of allocating aligned storage proper?
  • Is it OK (probably not) to use delete [] to deallocate afterwards or I need some special handling?

P.S I know that _aligned_malloc is not standard but rather MVSC specific.

101010
  • 41,839
  • 11
  • 94
  • 168
  • 1
    Wouldn't explicite destructor call be more appropriate? I mean something like `buf->~obj()` and then function to free memory? – W.F. Feb 24 '17 at 09:26
  • @W.F. I have a hinch that I must do something like you're suggesting and then call `_aligned_free`. – 101010 Feb 24 '17 at 09:28
  • 1
    On a side note: Is the `static_cast` really necessary here? AFAIK placement new takes a `void*` as parameter. – UnholySheep Feb 24 '17 at 10:16
  • 2
    You don't need the static_cast – M.M Feb 24 '17 at 11:41
  • @tehcnically array placement new is unusable because it may require unspecified bookkeeping overhead which you didn't allow for in your malloc. The "correct" way is to loop N times calling non-array placement new each time – M.M Feb 24 '17 at 11:48

1 Answers1

1

Isn't it sufficient for your task to use C++11 alignas?

For the question regarding delete[] - aligned_malloced memory should be freed using _aligned_free. Of course you need to call destructor first. Look this answer.

EDIT:

#include <malloc.h>

__declspec(align(64))
struct obj
{
    int i;
    char c;

    obj() : i{ 1 }, c{ 'a' } {}

    void* operator new[](size_t n)
    {
        return _aligned_malloc(n, 64);
    }

    void operator delete[](void* p)
    {
        _aligned_free(p);
    }
};

int main()
{
    int N = 10;
    obj *buf = new obj[N];

    buf[2].i = 1;

    delete[] buf;
    return 0;
}

On my machine it creates properly aligned storage, c-tors and d-tors are called because of new[] and delete[] instead of manual malloc/free.

Community
  • 1
  • 1
mpiatek
  • 1,313
  • 15
  • 16
  • Stupid enough, I'd like to contain my features to pre C++11. U see manager's opinion counts for 20 votes. – 101010 Feb 24 '17 at 09:35
  • @101010 second edit with what I believe is the correct way of doing this – mpiatek Feb 24 '17 at 10:52
  • @101010 - In my experience, manager's decisions count for a *lot* more than 20 votes. Changing compiler version is a non-trivial business risk, and if you have to support old versions of AIX/HPUX (spit!) You may not have the choice. – Martin Bonner supports Monica Feb 24 '17 at 10:55