简体   繁体   中英

why a 2-dimensional vector of auto_ptr in C++ does not work?

I am working on a 2-dimensional vector (vector of vector) to carry some pointers in C++.

std::vector< std::vector<object*> > data;

here object is a class and each entry of data carries a pointer to an object instance. I make it work in C++ but the memory management makes it hard to maintain when I apply it to other code. I did some research and someone suggests using a smart pointer instead. I try the following code

  #include <vector>
  #include <memory>
  using namespace std;
  
  int main(void) {
    vector< int > source = {1,2,3,4,5};
    vector< auto_ptr<int> > co;
    vector< vector< auto_ptr<int> > > all;

    co.push_back( auto_ptr<int>(&source[0]) );
    co.push_back( auto_ptr<int>(&source[2]) );
    co.push_back( auto_ptr<int>(&source[4]) ); // it works well up to here

    all.push_back(co); // but it crashs here
    return 0;
  }

One of the error messages is

C:/msys64/mingw64/include/c++/9.2.0/bits/stl_construct.h:75:7: error: no matching function for call to 'std::auto_ptr::auto_ptr(const std::auto_ptr&)' 75 | {::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

I wonder in what way I could add the vector< auto_ptr<int> > to another vector or list?

First, don't use std::auto_ptr . As you've found out, it cannot be used as an element of a vector, because it doesn't have an appropriate copy constructor. It has been deprecated since C++11 in favour of using std::unique_ptr instead. std::auto_ptr was removed from the language in C++17.

Second, objects pointed by &source[i] are owned by source . The objects aren't owned by the raw pointer that results from that expression, and there isn't even a way to transfer their ownership. As such, you mustn't give their ownership to a smart pointer. If you do, the behaviour of the program will be undefined as soon as those smart pointers are destroyed.

If you want to have a vector of vectors of smart pointers, here is a correct example:

std::vector<std::unique_ptr<int>> co;
std::vector<std::vector<std::unique_ptr<int>>> all;
for (auto i : source) {
    co.push_back(std::make_unique<int>(i));
}
all.push_back(std::move(co));

Bonus hints:

  • Unless you need to swap the rows, it is more efficient to use a single dimensional vector to represent a 2 dimensional array than to use a vector of vectors.
  • Unnecessary dynamic allocation can be expensive. Given that the vector elements themselves are already in dynamic storage, it is often best to store objects directly as elements instead of allocating them separately and storing smart pointers.

auto_ptr<T> is something you should never use. It has serious and unfixable design flaws. One of them is you cannot use it in a vector.

It was depricated and removed from the C++ standard for a reason.

Use std::unique_ptr<T> .

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