简体   繁体   English

成对向量和包含两个元素的结构向量的存储器布局的差异 - C ++ / STL

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

Is the layout in memory of test1 and test2 the same? test1test2的内存布局是否相同?

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

where mystruct is defined as: 其中mystruct定义为:

struct mystruct{
  int a;
  int b;
 };

Logically, std::pair<int, int> should be defined like that also. 逻辑上, std::pair<int, int>应该被定义。

There is however nothing about that on the standard and it is completely unguaranteed. 然而,标准上没有任何相关内容,而且完全没有保障。 You could take a look at the header files in your compiler to confirm that, but that doesn't prove anything. 您可以查看编译器中的头文件来确认,但这并不能证明什么。

Note: If you think it is absurd to be otherwise, I can give you an example how it could be defined otherwise. 注意:如果您认为不这样做是荒谬的,我可以举例说明如何定义它。 Imagine in the other stl template classes that use std::pair , they feel it would be convenient (for any reason), to have a pointer to the node containing the pair, in the pair. 想象一下在使用std::pair的其他stl模板类中,他们觉得在对中有一个指向包含该对的节点的指针是方便的(出于任何原因)。 This way, they could, internally, add a pointer to the pair class while not violating any rules. 这样,他们可以在内部添加指向对类的指针,同时不违反任何规则。 Your assumption would then cause havoc. 你的假设会造成严重破坏。 I would say it is unlikely for them to do such a thing, yes, but as long as they are not forced to that layout, anything can happen. 我会说他们不太可能做这样的事情,是的,但只要他们没有被迫采用这种布局,任何事情都可能发生。

If you see on the cplusplus.com, you'll see that this is the struct of a pair: 如果你在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) { }
}

Exactly the same, i would say, except some facts: Well, beginning with the fact that pairs are compatible with the std containers and all that, for example, maps. 完全相同,我会说,除了一些事实:好吧,从对与std容器兼容的事实开始,例如,映射。 Also, the pairs are already made, and already have constructors for you. 此外,这些对已经制作好了,并且已经有了构造函数。

EDIT: I also forgot to mention that you'll have std::make_pair for you, that allow you skipping allocating memory and making your own pair in a struct and you too have some comparison and assignment operators defined. 编辑:我也忘了提到你将拥有std :: make_pair,允许你跳过分配内存并在结构中创建自己的对,并且你也定义了一些比较和赋值运算符。

Yes, at least in Release mode it'll be the same size. 是的,至少在发布模式下它的大小相同。

You shouldn't use this knowledge to do some memory trickery though, because of two reasons: 你不应该使用这些知识做一些记忆诡计,原因有两个:

1) The std uses a lot of additional debugging stuff. 1)std使用了很多额外的调试工具。 That makes sizes of classes differ in debug and release mode. 这使得类的大小在调试和发布模式下有所不同。 So it might very well be that std::pair is larger in debug mode. 所以很可能std :: pair在调试模式下更大。

2) The std might change internally. 2)std可能会在内部发生变化。 There is no guarantee that std::pair won't change it's memory layout in a different std version. 无法保证std :: pair不会在不同的std版本中更改它的内存布局。 So if you rely on that you have to live with the fear that one day it might not work anymore. 因此,如果您依赖于此,您必须忍受有一天它可能不再起作用的恐惧。

In any reasonable implementation of std::pair they will have the same layout. std::pair任何合理实现中,它们将具有相同的布局。 But this begs the question of why does it matter? 但这引出了为什么重要的问题? You should not be doing a binary assignment from one to the other. 你不应该从一个到另一个进行二进制赋值。

You can add a copy constructor to the struct, either directly or by subclassing it. 您可以直接或通过子类化将结构构造函数添加到结构中。 You can also add a method that does the conversion the other way around. 您还可以添加以相反方式执行转换的方法。

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); }
 };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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