__restrict и shared_ptr хаки - PullRequest
       48

__restrict и shared_ptr хаки

2 голосов
/ 24 октября 2011

Безопасно ли следующее?

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;
};

Обратите внимание на __restrict для foo и bar.

Цель состоит в том, чтобы распределить память самоуничтожения, когда все псевдонимы объекта умерли.

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

Ответы [ 2 ]

2 голосов
/ 24 октября 2011

Здесь вам не нужны __restrict квалификаторы, и на самом деле вы не должны их использовать, потому что __restrict должен сообщать компилятору, что у вас нет псевдонимов для той же памяти, но на самом делеу вас есть псевдонимы - foo и data являются псевдонимами для одной и той же памяти.

Я думаю, что семантика вашего кода в порядке, в противном случае.Ваш a.foo все еще действителен , а a.foo недействителен условия будут выполняться.

0 голосов
/ 24 октября 2011

Это небезопасно, потому что malloc не вызывает конструктор, а free не вызывает деструктор.Чтобы это было безопасно, вам нужно вручную добавить эти вызовы:

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;
}
...