对的向量和包含两个元素的结构体的向量的内存布局的区别- c++ /STL

Difference in memory layout of vector of pairs and vector of structs containing two elements - C++/STL

本文关键字:向量 区别 c++ STL 布局 结构体 包含两 元素 内存      更新时间:2023-10-16

test1test2在内存中的布局是否相同?

std::vector<std::pair<int,int> > test1;
std::vector<mystruct>       test2;

mystruct定义为

struct mystruct{
  int a;
  int b;
 };

如果你在cplusplus.com上看到,你会看到这是一对的结构体:

template <class T1, class T2> struct pair
{
  typedef T1 first_type;
  typedef T2 second_type;
  T1 first;
  T2 second;
  pair() : first(T1()), second(T2()) {}
  pair(const T1& x, const T2& y) : first(x), second(y) {}
  template <class U, class V>
    pair (const pair<U,V> &p) : first(p.first), second(p.second) { }
}

我想说完全一样,除了一些事实:首先,pair与std容器和所有这些兼容,例如映射。而且,这些对已经生成,并且已经为您提供了构造函数。

编辑:我还忘了提一下,您将有std::make_pair,它允许您跳过分配内存并在结构体中创建自己的pair,并且您也定义了一些比较和赋值操作符。

逻辑上,std::pair<int, int>也应该这样定义。

然而,在标准上没有关于这一点的任何内容,它完全不能保证。您可以查看编译器中的头文件来确认这一点,但这并不能证明任何东西。

注:如果你认为它是荒谬的,我可以给你一个例子,如何可以定义它。想象一下,在使用std::pair的其他stl模板类中,它们认为(出于任何原因)在pair中有一个指向包含pair的节点的指针会很方便。这样,它们就可以在内部向pair类添加指针,而不违反任何规则。你的假设会造成混乱。我想说他们不太可能做这样的事情,是的,但只要他们不被迫这样布局,任何事情都可能发生。

是的,至少在发布模式下它的大小是一样的。

你不应该使用这些知识来做一些内存欺骗,因为两个原因:

1)std使用了很多额外的调试工具。这使得类的大小在调试和发布模式下有所不同。因此,在调试模式下,std::pair很可能更大。

2)std可能在内部发生变化。不能保证std::pair在不同的std版本中不会改变它的内存布局。因此,如果你依赖于这一点,你就必须生活在恐惧中,因为有一天它可能不再有效。

在任何合理的std::pair实现中,它们都将具有相同的布局。但这引出了一个问题:为什么这很重要?你不应该从一个到另一个进行二进制赋值。

您可以直接或通过子类化为结构体添加复制构造函数。您还可以添加一个方法,以相反的方式进行转换。

struct mystruct{
  int a;
  int b;
  mystruct(const std::pair<int,int> &rhs) { a=rhs.first; b=rhs.second; }
  std::pair<int,int> as_pair() { return std::make_pair(a, b); }
 };