Question

Is the following safe?

struct K { ... }

struct A
{
    A(int psize) : size(psize), foo(nullptr), bar(nullptr)
    {
        auto dataptr = (K*)_aligned_malloc(sizeof(K) * psize * 2, 32);
        data = shared_ptr<K>(dataptr, ptr_fun(_aligned_free));
        foo = data.get();
        bar = data.get() + psize;
    }   
    K* __restrict foo;
    K* __restrict bar;
private:
    shared_ptr<K> data;
};

Note the __restrict on foo and bar.

The goal is to have allocated memory self destruct when all object aliases have died.

{
    A a(1000);
    { 
        A o = a; 
    }
    //a.foo is still valid
}
//a.foo is invalid
Was it helpful?

Solution

You don't need __restrict qualifiers here, and in fact you shouldn't use them, because __restrict is supposed to tell the compiler that you don't have any aliases to the same memory, but in fact you do have aliases -- foo and data are aliases to the same memory.

I think the semantics of your code are fine, otherwise. Your a.foo is still valid and a.foo is invalid conditions will be true.

OTHER TIPS

That is not safe because malloc doesn't call the constructor and free doesn't call the destructor. For that to be safe you need to manually add those calls:

A(int psize) : size(psize), foo(nullptr), bar(nullptr)
{
    auto dataptr = (K*)_aligned_malloc(sizeof(K) * psize * 2, 32);
    new(dataptr) K();
    data = shared_ptr<K>(dataptr, [](K *k){ k->~K(); _aligned_free(k) ));
    foo = data.get();
    bar = data.get() + psize;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top