超出范围的向量运算符[]导致崩溃

Vector operator [ ] out of range leads to a crash?

本文关键字:崩溃 运算符 范围 向量      更新时间:2023-10-16
vector<int> iV2_func{2, 3, 4, 5};
drucke(iV2_func);
  for (j=0; j<=iV2_func.size(); j++) { 
    iV2_func[j] = quadfunc(iV2_func[j]+1);
 }
 drucke(iV2_func);

我目前正在为即将到来的c++考试练习,由于我是在Java环境中长大的,所以我对c++的所有习惯并不熟悉。给定的代码是在一个main() -方法,一切必要的已包括等。任务是检测六个for循环中的错误,这些循环使用不同的方法将参数与自身相乘,例如宏、模板、内联函数等。drucke()输出vector的单个成员。这里的for循环显然是越界的,但是由于没有使用.at() -Method,因此不会抛出异常,相反,我们最终会有未定义的行为。

当我启动程序时,程序崩溃所有行都打印出来之后。甚至在之后的for循环这个for循环也被执行了,所有的东西都被打印出来了。似乎错误发生在main()方法的末尾,而不是当程序访问超出范围的索引时,但错误肯定在于该索引,因为程序不会崩溃。那么,究竟是怎么回事,程序似乎与这些代码一起工作,但最后仍然崩溃?

那么,究竟是怎么回事,程序似乎与这些代码一起工作,但最后仍然崩溃?

很可能您已经在调试构建配置中编译了程序。在调试构建中,分配的内存区域的"边界"通常用金丝雀值填充,以便在内存释放时可以检测到OOB写。当检测到这种被杀死的金丝雀时,内存释放程序将中止程序。

为什么需要金丝雀值?因为在现代操作系统上,内存分配和保护只发生在页面粒度上,通常是4k。因此,只要您的内存访问保持在操作系统提供的映射范围内(这是页面大小的倍数),操作系统就无法检测到非法访问。然而,内存分配器将在这些页内汇集分配,并且由于在这样一个区域内的对象之间没有保护,因此很难检测到破坏"邻居"的OOB访问。因此,金丝雀值,以便在开发中可以报告这样的OOB访问。