标准向量内存分配linux与Windows编译器

时间:2018-07-18 19:28:47

标签: c++ linux visual-c++ vector stl

一个非常简单的程序,用于测试Linux(Intel 18.0)上的Intel编译器和Windows(MSVC 2015)上的Visual c ++之间的STL实现。

  1. 从根本上讲,如何使Linux致命/崩溃与Windows相同(因为我有一个庞大的代码库)。从技术上讲,我期望从Linux发出信号11,无论我测试的向量大小如何,都不会每次都抛出垃圾值。

  2. 有人可以解释幕后发生的事情(明智的内存分配及其规则,以及是否取决于实现/平台/编译器)吗?仅出于我的理解。

'

#include "iostream"
#include "vector"
using namespace std;
int main(int argc,char* argv[])
{   
   vector<int> v;
   //v.resize(5);  (my bad, please ignore this, i was testing and posted incorrect version)
   cout<<"Initial vector size: "<<v.size()<<endl;
   for(int i=1;i<=5;++i)
   {
       v.push_back(i);
   }
   cout<<"size of vector after: "<<v.size()<<endl;

   for(int j=5;j>=0;--j) // Notice my upper bound.
   {
      cout<< "printing " <<v[j]<<std::endl;
   }
   return 0;
}

两者在编译时都没有遇到任何问题。随后,Windows崩溃并发出一条漂亮的消息“向量下标超出范围”,而linux每次都抛出一些垃圾值并继续。

1 个答案:

答案 0 :(得分:2)

假设您误输入了v.resize(5),以下是一些答案:

  

如何使Linux致命/崩溃与Windows相同(因为我有一个庞大的代码库)。

使用std::vector::at()来验证索引并通过设计引发异常。 std::vector::operator[]并非要验证索引,即使某个平台针对某些配置进行了验证(看起来像调试中的Windows编译器也具有这种验证功能),也无法在任何地方都要求它。

  

从技术上讲,我期望从Linux发出信号11,无论我测试的向量大小如何,都不会每次都抛出垃圾值。

这是您期望的问题。给std::vector::operator[]赋予无效索引会导致未定义的行为,并且您不能指望给信号11或其他特定信号。

预付款:

std::vector::operator[]

  

返回对在指定位置pos的元素的引用。 不执行边界检查

std::vector::at()

  

如果pos不在容器的范围内,则会引发std :: out_of_range类型的异常。

强调是我的。

关于内存分配,它是特定于实现的,为了提高效率,它们中的大多数不会为5个元素精确分配内存,而是提前分配内存,因此这就是Linux上的代码不会粉碎,而是产生垃圾的原因,因为您从未初始化的内存中读取值。但这可以随时改变,您不应该以任何方式依赖此行为。