一个非常简单的程序,用于测试Linux(Intel 18.0)上的Intel编译器和Windows(MSVC 2015)上的Visual c ++之间的STL实现。
从根本上讲,如何使Linux致命/崩溃与Windows相同(因为我有一个庞大的代码库)。从技术上讲,我期望从Linux发出信号11,无论我测试的向量大小如何,都不会每次都抛出垃圾值。
有人可以解释幕后发生的事情(明智的内存分配及其规则,以及是否取决于实现/平台/编译器)吗?仅出于我的理解。
'
#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每次都抛出一些垃圾值并继续。
答案 0 :(得分:2)
假设您误输入了v.resize(5)
,以下是一些答案:
如何使Linux致命/崩溃与Windows相同(因为我有一个庞大的代码库)。
使用std::vector::at()
来验证索引并通过设计引发异常。 std::vector::operator[]
并非要验证索引,即使某个平台针对某些配置进行了验证(看起来像调试中的Windows编译器也具有这种验证功能),也无法在任何地方都要求它。
从技术上讲,我期望从Linux发出信号11,无论我测试的向量大小如何,都不会每次都抛出垃圾值。
这是您期望的问题。给std::vector::operator[]
赋予无效索引会导致未定义的行为,并且您不能指望给信号11或其他特定信号。
预付款:
返回对在指定位置pos的元素的引用。 不执行边界检查。
如果pos不在容器的范围内,则会引发std :: out_of_range类型的异常。
强调是我的。
关于内存分配,它是特定于实现的,为了提高效率,它们中的大多数不会为5个元素精确分配内存,而是提前分配内存,因此这就是Linux上的代码不会粉碎,而是产生垃圾的原因,因为您从未初始化的内存中读取值。但这可以随时改变,您不应该以任何方式依赖此行为。