1

This is just for learning purposes, I know I can just use a vector but I have

const int N = 1e3;
auto my_arr = std::make_unique<std::array<int, N>>();

// To access it I have to do this - why [0][0] twice?
my_arr.get()[0][0] = 1;

// Getting the size for fun
std::cout << sizeof(my_arr.get()) << "\n"; // outputs 8
std::cout << sizeof(my_arr.get()[0]) << "\n"; // outputs 800000000
std::cout << sizeof(my_arr.get()[0][0]) << "\n"; // outputs 8

I understand that .get() returns a pointer to the managed object but I don't understand why I need to do my_arr.get()[0][0] twice?

7
  • 4
    my_arr.get() returns a pointer. Dereferencing a pointer and indexing it at position 0 are the same thing. ptr[0] is defined to be the same at *(ptr + 0) Commented Oct 11, 2018 at 17:37
  • 2
    my_arr.get()[0] is the same as *(my_arr.get()). You should use the latter because there's no my_arr.get()[1]. Commented Oct 11, 2018 at 17:38
  • Are you actually sure about const int N = 1e3;? That looks kind of weird. Also remember that std::unique_ptr is a replacement for a pointer, so strictly speaking you'll get a pointer to a pointer decayed from an array, and you'll end up with more or less sizeof(int). Commented Oct 11, 2018 at 17:38
  • 2
    @n.m. actually op should use *my_arr without get Commented Oct 11, 2018 at 17:39
  • @πάνταῥεῖ what looks weird about it? Commented Oct 11, 2018 at 17:52

4 Answers 4

7

my_arr.get() gives you a std::array<int, N>*. Since you have a pointer doing pointer[0] is the same as *pointer. So you don't actually need my_arr.get()[0][0] and you can instead use

(*my_arr.get())[0]

to show that you are dereferencing the pointer. In fact, you could just use

(*my_arr)[0]

because operator * is overloaded for std::unique_ptr and it will return a reference to the pointed to thing.

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

Comments

5

Well, you don't have to do that, but it works.

my_arr.get() returns a std::array<int,N>*

Like any pointer, you can index it like an array.

my_arr.get()[0] returns a reference to the first element in your 'array' of arrays.

You can then use std::array's indexing operator to get an element.

my_arr.get()[0][0] returns a reference to the element you want.

Alternatively, you could write:

my_arr->at(0)
my_arr->operator[](0)
(*my_arr)[0]
*my_arr->data()

1 Comment

Thanks for providing those alternatives, they were very helpful
4

You probably don't want to do this:

auto my_arr = std::make_unique<std::array<int, N>>();

Unless you really specifically want an array<int, N>. If what you just want to do is dynamically allocate N ints and manage that with a unique_ptr, that's:

auto my_arr = std::make_unique<int[]>(N);

The advantages here are:

  • N can be a runtime value, it doesn't have to be a constant-expression.
  • unique_ptr<T[]>::operator[] exists and does what you want, so my_arr[2] does index into the array.

Comments

3

As you said yourself .get() returns a pointer to the managed object.

So it is std::array<int, N>* what you return and not std::array<int, N>:

std::array<int, N>* array_ptr = my_arr.get();

So either write (*my_arr)[0] or (*my_arr.get())[0]

Comments

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.