2

I am trying to declare and initialize a unique_ptr holding a class array

This is a sample I am using to solve a memory management issue with my project. I can declare the pointer but I am not able to initialize it.

class CrewMember
{   
};


class SpaceShip
{

// generates error
std::unique_ptr<CrewMember[3][3]> ship_crew_members = std::make_unique< new CrewMember[3][3]>; 

// compiles fine
std::unique_ptr<CrewMember[3][3]> ship_crew_members;

};

errors received:

call to non-constexpr function 'void* operator new ' std::unique_ptr ship_crew_members = std::make_unique< new CrewMember[3][3]>;
^
cannot resolve overloaded function 'make_unique' based on conversion to type 'std::unique_ptr' std::unique_ptr ship_crew_members = std::make_unique< new CrewMember[3][3]>;

8
  • 1
    make_unique is a function template. You need to do make_unique<Type>(). Commented Jul 22, 2019 at 2:06
  • std::make_unique< new CrewMember[3][3]> 90% sure you can't use new in this context. Commented Jul 22, 2019 at 2:11
  • Also, it should be something more along the lines of std::make_unique<CrewMember[3][3]>(), though I'm not sure this is completely correct. Commented Jul 22, 2019 at 2:13
  • @L.F. and Chipster I will give that a shot. Thank you for the quick response! Commented Jul 22, 2019 at 2:15
  • Tried this: cpp std::unique_ptr<CrewMember[3][3]> ship_crew_members = std::make_unique< CrewMember[3][3]>(); recieved pastebin.com/Kma1Q4S8 Commented Jul 22, 2019 at 2:24

1 Answer 1

1
  1. std::unique_ptr stores a pointer to either a single object, or to a one-dimensional array. Multi-dimensional arrays are not supported. It can theoretically store a pointer to a multidimensional array, if you do an evil cast, but you really should not.

  2. If you really want to use std::unique_ptr to store a multidimensional array, you'd need to do some extra work and use a one-dimensional array and then calculate the offset for the multidimensional index yourself (e.g. [1][2] becomes 1*3+2).

  3. std::make_unique is a function template. The template parameter needs to be a proper type, which either is a class or a class array (but without the size). If your type is an array and you give std::make_unique a size as parameter, it will create a std::shared_ptr that points to an array of that size and uses the proper delete[] operator on that array when it gets destructed.

All together that would look something like so:

std::shared_ptr<CrewMember[]> ship_crew_members = std::make_shared<CrewMember[]>(9);

However I strongly advice against doing this. Much simpler is to use any of the std containers, e.g. std::vector:

std::vector<std::vector<CrewMember>> ship_crew_members;

This gives you a multidimensional container of varying size, that you can add elements to or remove elements from.

Or std::array for a fixed size multidimensional array:

std::array<std::array<CrewMember, 3>, 3> ship_crew_members;
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @MaxVollmer you helped me greatly! I will implement the code and explanation you have given me, into my project!

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.