std矢量内存分配linux与windows编译器

std vector memory allocation linux vs windows compilers

本文关键字:windows 编译器 linux 分配 内存 std      更新时间:2023-10-16

一个非常简单的程序,用于测试linux上的英特尔编译器(英特尔18.0(和windows上的visual c++(MSVC 2015(之间的STL实现。

  1. 主要是,如何以与windows相同的方式使linux致命崩溃(因为我有一个巨大的代码库(。从技术上讲,我期待着来自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崩溃,并显示一条漂亮的消息"vector subscript out range",而linux每次都抛出一些垃圾值并继续。

假设您错误地放置了v.resize(5),以下是一些答案:

如何以与windows相同的方式使linux致命崩溃(因为我有一个巨大的代码库(。

使用std::vector::at()验证索引并按设计抛出异常。std::vector::operator[]不假设验证索引,即使某些平台对某些配置进行了验证(看起来调试中的Windows编译器有这样的验证(,也不能到处要求它。

从技术上讲,我期待着来自linux的信号11,而不是每次都抛出垃圾值,无论我测试的向量大小如何。

这是您所期望的问题。给std::vector::operator[]提供无效的索引会导致未定义的行为,并且您不能期望它会给出信号11或其他特别的东西。

FYR:

std::vector::operator[]

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

std::vector::at((

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

重点是我的。

至于内存分配,它是特定于实现的,它们中的大多数不会为5个元素精确分配内存,而是提前分配更多的内存,以提高效率,所以这就是为什么Linux上的代码在从未初始化的内存中读取值时没有崩溃,而是产生垃圾的原因。但这种情况随时都可能改变,你不应该以任何方式依赖这种行为。