c++ - 标准向量内存分配 linux vs windows 编译器
问题描述
一个非常简单的程序,用于测试 Linux 上的英特尔编译器(英特尔 18.0)和 Windows 上的 Visual c++(MSVC 2015)之间的 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 每次都抛出一些垃圾值并继续。
解决方案
假设你打错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 上的代码没有崩溃,而是在你读取值时产生垃圾来自未初始化的内存。但这可能随时改变,你不应该以任何方式依赖这种行为。
推荐阅读
- java - 我正在努力从这个嵌套的 for 循环中正确格式化我的输出
- c++ - 点云库 (PCL) - 声明点云时应使用 ::Ptr 的经验法则?
- java - 在另一个字符串中查找一个字符串的字母
- java - 如何使用 Java 创建格式化的 json?
- php - 如何防止直接 URL 调用但允许来自我的 Android 应用程序
- python - describe() 返回所有空值
- javascript - 如何使用javascript更改科尔多瓦的位置
- android - 在 android 中部署 Ionic 4 应用程序抱怨 Android SDK 许可证不被接受
- java - Hibernate:什么时候应该使用 Cascade.ALL,什么时候应该单独指定它们
- node.js - 如何将购物车数据上传到 cookie?