-2

I would like to identify a canonical approach to allocating the equivalent of an array of pointers to pointers to int (like: int ** int_array), but using unique_ptr.

I would like a C++11 solution that is extensible to an array of pointers to pointers to an instance of a class, if possible (I've used ints here to simplify, and I realize there may be other issues when using class instances).

I understand how to create a fixed-size array of unique_ptr where the size is known in advance. The goal is to do the same where the array size is not known.

I have looked at a number of related solutions including the one below, but they seem to deal only with fixed allocation of unique_ptr arrays (that is, the size of the array of unique_ptr is already known in advance):

Proper way to create unique_ptr that holds an allocated array

I've implemented a simple program that attempts to demonstrate and compare 3 approaches: traditional dynamic creations of pointers, a fixed array of unique_ptr, and the goal: a dynamic array of unique_ptr.

#include <iostream> // include iostream
#include <memory> // include memory

using namespace std;

int main() {

  cout << "Testing dynamic arrays of pointers\n";

  int **num_array; // typical dynamic array of pointers to int
  int count;       // count of ints the user wants to generate

  unique_ptr<int[]> f_num_array(new int[200]()); 
       // above: fixed array of unique pointers to int - not what I want

  unique_ptr<int[]> u_num_array; 
       // above:  GOAL: dynamic array of unique pointers to int

  int sum, u_sum, f_sum; 
       // above: test sum of each type of array (should match user count)

  cout << "How many pointers would you like? ";

  cin >> count; // get user input

  num_array = new int*[count]; // allocate array of pointers on heap

  //u_num_array = new int[count](); // GOAL - would like to do this
       // above: ERROR: no overload for =; cannot allocate this way

  for(int i=0; i<count; i++) { // allocate ints and store pointer
    num_array[i] = new int(1); // pointer to an int on the heap 
    f_num_array[i] = 1; // assign 1 to the pre-allocated unique pointer array

    unique_ptr<int> u_tmp(new int(1)); // temporary unique_ptr to int
    // u_num_array[i] = u_tmp; // GOAL - would like to do this...
        // ERROR: cannot assign unique_ptr this way
  }

  sum = 0; f_sum = 0; u_sum = 0; // init our sums to verify

  for(int i=0; i<count; i++){
    sum += *(num_array[i]); // summing our traditional array of pointers
    f_sum += f_num_array[i]; // summing our fixed unique array of pointers
  }

  cout << "Sum = " << sum << "\n";
  cout << "Sum (fixed unique_ptr array) = " << f_sum << "\n";
  cout << "Sum (dynamic unique_ptr array) = " << u_sum << "\n";

  delete[] num_array; // delete the dynamic array
  f_num_array.release();  // delete the dynamic array

  cout << "\nDone!\n"; 

}
Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
Jeff
  • 35
  • 5

1 Answers1

3
#include <iostream>
#include <memory>
#include <vector>

int main() {

  std::cout << "Testing dynamic arrays of pointers\n";

  //int **num_array; - Never use except you are forced by some external interface.
  int count = 0; // Always initialize variables

  std::vector<std::unique_ptr<int>> num_array; 

  std::cout << "How many pointers would you like? ";

  std::cin >> count; // get user input

  num_array.resize(count);
  for (auto& p : num_array) // You can do it with some algorithm, but I prefer this way
    p = std::make_unique<int>(1);

  int sum = 0; // Don't declare variables before you use them.
  for (auto& p : num_array)
    sum += *p;

  std::cout << "Sum = " << sum << "\n";

  num_array.clear();

  std::cout << "\nDone!\n"; 

}
aparpara
  • 2,171
  • 8
  • 23
  • Thanks gentlemen. I wish I had access to c++14, but I do not in this case. I guess my question was "is this possible in c++11 - I will assume that it is not possible, but if anyone knows, it would be great to put a pin in that. I'm pretty clear containers are a better way to go and thank you definitely for demonstrating that! – Jeff Apr 07 '19 at 18:23
  • 1
    @Jeff This will compile as C++11 if you change `p = std::make_unique(1);` to `p = std::unique_ptr(new int(1));` – Blastfurnace Apr 07 '19 at 18:35