简体   繁体   中英

Can one declare an array of smart pointers to std::vector<int> on the stack?

It's possible to declare a fixed-size array of raw pointers on the stack, which can be used to dynamically allocate memory (objects) at runtime. I'm trying to replace raw pointers with smart pointers, but this pattern is failing.

The following code summarizes the problem, hope it's not too verbose:

#include <iostream>
#include <vector>
#include <memory>
const int SIZE = 10;

    //older method of declaring an array of std::vector<int> pointers with
    //memory leak risks, using automatic (stack-based) allocation for the 
    //array of pointers, dynamic (heap-based) allocation for the vectors:

    std::vector<int>* arr[SIZE];
    for (int i = 0; i < SIZE; i++) {
        arr[i] = new std::vector<int>;
    }
    for (int i = 0; i < SIZE; i++) {
        arr[0]->push_back(i);
    }
    for (int val : *arr[0]) {
        std::cout << val << " ";    //prints 0 - 9 as expected
    }

That works as usual, but when trying to implement smart pointers I can only get a smart pointer to an array of std::vector to work, ie:

    //declaring smart pointer to an array of std::vector<int>, which is not
    //automatic (stack-based) allocation of the array

    std::unique_ptr<std::vector<int>[]> arr2 (new std::vector<int>[SIZE]()); 
    for (int i = 0; i < SIZE; i++) {
        arr2[0].push_back(i);
    }
    for (int val : arr2[0]) {
        std::cout << val << " ";    //prints 0 - 9 as expected
    }

As far as I can tell, this is not something smart pointers support? :

    //attempting to declare an array of smart pointers to std::vector<int>

    std::unique_ptr<std::vector<int>> arr3[SIZE];
    for (int i = 0; i < SIZE; i++) {
        std::cout << &arr3[i] << std::endl;         //prints memory locations
        if (arr3[i]->empty()) {                     //seg faults @ runtime
            std::cout << "empty vector\n";          
        }
        arr3[i] = new std::vector<int>;             //won't compile
    }

(Please let me know if there are basic problems with this pattern as well)

In the last code block, it looks like arr3 is getting memory assigned but I cannot figure out how to use it to create a new std::vector.

 //older method of declaring an array of std::vector<int> pointers with //memory leak risks, using automatic (stack-based) allocation for the //array of pointers, dynamic (heap-based) allocation for the vectors: 

Automatic storage duration arrays don't leak. Their elements can, however. For example, when they are pointers that point to dynamically allocated elements. Smart pointers are there to replace raw pointers, so do just that - replace T* with, for example, std::unique_ptr<T> . Do not replace an array of automatic storage duration with a smart pointer - at most use std::array . I believe you are looking for something like this:

std::unique_ptr<std::vector<int>> arr3[SIZE];
// or better - std::array<std::unique_ptr<std::vector<int>>, SIZE> arr3{};
for (int i = 0; i < SIZE; i++) {
    arr3[i] = std::make_unique<std::vector<int>>(); // notice the syntax...
    // ... and the fact that you first allocate the vector, *then* use the ->empty()
    std::cout << &arr3[i] << std::endl;         
    if (arr3[i]->empty()) {                     
        std::cout << "empty vector\n";          
    }     
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM