1

I'm writing some code which uses SSE/AVX via intrinsics. Therefore, I need arrays that are guaranteed to be aligned. I am attempting to make these via _aligned_malloc with the following code:

template<class T>
std::shared_ptr<T> allocate_aligned( int arrayLength, int alignment )
{
   return std::shared_ptr<T>( (T*) _aligned_malloc( sizeof(T) * arrayLength, alignment ), [] (void* data) { _aligned_free( data ); } );
}

My question is, how can I reference the data in my arrays with the usual array index notation? I know unique_ptr has a specialization for arrays that calls delete[] for destruction and allows for array index notation (ie myArray[10] to access the 11th element of the array). I need to use a shared_ptr however.

This code is giving me problems:

void testFunction( std::shared_ptr<float[]>& input )
{
   float testVar = input[5]; // The array has more than 6 elements, this should work
}

Compiler output:

error C2676: binary '[' : 'std::shared_ptr<_Ty>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>          with
1>          [
1>              _Ty=float []
1>          ]

Is there a way to do this? I am still pretty new to using smart pointers, so I might be screwing up something simple. Thanks for any help!

7
  • 1
    Aside: your allocation function doesn't construct the objects in your array, and the destructors won't get called upon cleanup. You should be careful to only use it on trivial types -- or better yet, do a static_assert in the function to ensure that std::is_trivial<T>::value is true (I think that's the check you want to make). Or possibly even better, use SNIFAE to eliminate nontrivial types from the overload. Alternatively, change the function to construct and destroy objects appropriately. Commented Apr 13, 2015 at 19:59
  • Why no overloads for operator new / delete in the classes which like to be aligned? Commented Apr 13, 2015 at 20:03
  • 1
    I don't think you can use allocate_aligned with float[], because sizeof cannot be applied to that. Commented Apr 13, 2015 at 20:04
  • @typ1232: You're correct, T should be simply float, and the return type std::shared_ptr<T[]> Commented Apr 13, 2015 at 20:25
  • @Hurkyl I am just using this on floats, doubles, and complex arrays (complex implemented as a struct of 2 floats) so that shouldn't be an issue, but I should add a check in there. Good idea, thanks. Commented Apr 13, 2015 at 20:30

2 Answers 2

2

What you exactly want is not actually possible in C++.

The reasons are simple: shared_ptr does not implement operator[] for them and operator[] must be implemented as a member.

However, you can get very close with one of three options:

  1. Simply use a vector with a member type of the correct alignment (e.g. __m128 from xmmintrin.h) and drop all the other work.

  2. Implement a class similar to shared_ptr yourself (possibly using std::shared_ptr under the hood)

  3. Extract the raw pointer when you need it (float testVar = input.get()[5];) and index it instead.

Sign up to request clarification or add additional context in comments.

3 Comments

hmm okay... i was afraid that might be the answer. i guess i'll have to think about how i want to do this. thank you!
@RyanP Yeah, I ran into similar problems before. Let me suggest that using vector<__m128> makes things very simple (at least it did for me).
I'm actually using the shared_ptr to hold large arrays of image data. So I need the image data to be aligned so that I don't need to use unaligned loads and stores. I suppose I could hold the images in a vector but I was hoping to not have to significantly alter the existing code base.. just make it a little less error-prone.
0

For those facing a similar problem, the following may help. Instead of having a shared pointer to an array, use a shared pointer to a pointer. You can still use the index notation, but you need to dereference the shared pointer before that:

std::shared_ptr<int*> a = std::make_shared<int*>(new int[10]);
(*a)[0] = 5;
std::cout << (*a)[0] << std::endl;

1 Comment

Does it address the arrays that are guaranteed to be aligned requirement?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.