Custom std :: allocator for classes with new operator replaced

I recently replaced some Vector / Matrix classes with ones that use SSE and now I am confident that the memory is correctly aligned.

Following the advice in the answer to this question , I replaced the new / delete operator for classes that require it, and started working on a custom allocator to use with STL containers - however, there is some conflict between the two:

To get started, I just copied and pasted the fetch allocator class from here , which compiles fine when I use it with the std :: vector of the types in question, without my custom new / delete, but when I replace those functions. I get the error "There is no suitable function to call" operator new "from the construct () function,

void    construct(pointer p, const T& t)    { new(p) T(t); }

      

I'm guessing that the fact that I replaced the "regular" new one somehow closed the new placement? However, given that I can't write my own new place to find it, I'm not really sure what to do ... I'm a newbie (NPI) for all user memory, so any advice would be greatly appreciated!

I am compiling on Linux using Clang v3.4 (or gcc 4.1.2); not using C ++ 11.

Many thanks.

+3


source to share


3 answers


Canonical allocator :: construct calls::new((void *)p) T(val)

Omitting ::

, you can start looking up the name using the class T

where it found operator new

in the class and did not continue anymore (the name lookup stops at the first scope where any matching names are found, even if the best candidate exists in some closing scope)



(void casting happens in case the user sneaks into a new overloaded global overload that takes a nonvoid pointer parameter)

PS: as correctly pointed out in the comments, "given that I cannot write my own new place" is not a correct assumption. You cannot replace the global placement with a new one, but you can certainly write a new place to place a class, which will then be picked up by a class search. Check out cppreference for a summary of distribution functions.

+4


source


I would suggest using Boost aligned_allocator :

#include <boost/align/aligned_allocator.hpp>
#include <immintrin.h>
#include <vector>

struct m128i {
    // FIXME: ctors/opers with intrinsics would be nice (required?)
    __m128i data;
}

int main()
{
    std::vector<m128i, boost::alignment::aligned_allocator<m128i, 16> > v;
    v.emplace_back();
}

      



Note. I've updated this to use a structure that wraps an inner member. There are many libraries that do this. The reason for this is simple: the vector_size attribute distinguishes __m128i from __m256i from __m512i, and templates ignore type attributes, so I believe they all ended up with the same extension as "long long" (or float / double in case of non-i and d types ).

+1


source


I would use my starting point as the allocator given here: http://en.cppreference.com/w/cpp/concept/Allocator . This is actually a minimal allocator. In particular, you don't need to write at all construct

. allocator_traits

if it doesn't detect that your allocator has a method construct

, it will just call the new placement for you, looking at the call correctly with ::

(as Cubbi notes), so you don't have this problem: http://en.cppreference.com/w/ cpp / memory / allocator_traits / construct .

I probably won't write custom new / delete at all. It is easy enough to write a custom allocator and your Vector / Matrix classes manage their data std::vector

with a custom allocator.

0


source







All Articles