What is the size of an auto_ptr?

2019-09-04 18:13发布

问题:

Does an auto_ptr have the same size as a pointer?

I have to substitute it with a boost::scoped_ptr, and I was wondering if these two data types have the same size.

回答1:

You can pretty easily find out what the sizes are by simply doing this:

#include <iostream>
#include <memory>

#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>

int main() {
  std::cout << "raw pointer: " << sizeof(int*) << std::endl;
  std::cout << "auto-ptr: " << sizeof(std::auto_ptr<int>) << std::endl;
  std::cout << "unique-ptr: " << sizeof(std::unique_ptr<int>) << std::endl;
  std::cout << "shared-ptr: " << sizeof(std::shared_ptr<int>) << std::endl;
  std::cout << "boost scoped-ptr: " << sizeof(boost::scoped_ptr<int>) << std::endl;
  std::cout << "boost shared-ptr: " << sizeof(boost::shared_ptr<int>) << std::endl;
  return 0;
};

On my platform (64bit), with GCC 4.8.2 and Boost 1.55, I get this output:

raw pointer: 8
auto-ptr: 8
unique-ptr: 8
shared-ptr: 16
boost scoped-ptr: 8
boost shared-ptr: 16

Of course, there is no strict guarantee that these results will be the same anywhere. In other words, the standard does not require that auto-ptr or unique-ptr (C++11) be of the same size as a regular (raw) pointer. As far as I can see, the Boost documentation does not explicitly give that guarantee either for scoped-ptr, but they do give the following statement:

Because scoped_ptr is simple, in its usual implementation every operation is as fast as for a built-in pointer and it has no more space overhead that a built-in pointer.

I would say that it is pretty safe to assume that the above statement holds true for any decent implementation of either auto-ptr, unique-ptr or scoped-ptr. If you test it on some platform and get a result that contracts that, then I would consider that implementation to be worthless unusable garbage. There is no sensible reason for either one of these smart pointers to contain anything more than a single pointer (except for unique-ptr which could have to make place for a non-empty custom deleter object, but otherwise, should have the same size as the other two).

And by the way, if you are also curious about why shared-ptr has a size of 16 in my tests. That's because the features of shared-ptr make it so that individual shared-pointers must contain 2 pointers: one is a (possibly aliasing) pointer to the object in question, and one is a pointer to the reference-counting shared data structure that all its associated shared- or weak- pointers use. The fact that shared-pointers can point to something other than what is actually being managed by the reference-counting (or some related but different pointer, like a pointer to a member or base- / derived- class) is the reason why it needs that local pointer in addition to the pointer to the reference-counting shared data (and also, it also performs better when the pointer to the object can be obtained directly, without having to go through the shared data structure). But this is still a reasonable overhead for when you need reference-counting.