- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我写了一个非常简单的程序来尝试检查附加到缓冲区溢出的未定义行为。具体来说,关于当您对分配空间之外的数据执行读取时会发生什么。
#include <iostream>
#include<iomanip>
int main() {
int values[10];
for (int i = 0; i < 10; i++) {
values[i] = i;
}
std::cout << values << " ";
std::cout << std::endl;
for (int i = 0; i < 11; i++) {
//UB occurs here when values[i] is executed with i == 10
std::cout << std::setw(2) << i << "(" << (values + i) << "): " << values[i] << std::endl;
}
system("pause");
return 0;
}
当我在 Visual Studio 上运行这个程序时,结果并不令人惊讶:读取索引 10
产生垃圾:
000000000025FD70
0(000000000025FD70): 0
1(000000000025FD74): 1
2(000000000025FD78): 2
3(000000000025FD7C): 3
4(000000000025FD80): 4
5(000000000025FD84): 5
6(000000000025FD88): 6
7(000000000025FD8C): 7
8(000000000025FD90): 8
9(000000000025FD94): 9
10(000000000025FD98): -1966502944
Press any key to continue . . .
但是当我将这个程序输入 Ideone.com 的在线编译器时,I got extremely bizarre behavior:
0xff8cac48
0(0xff8cac48): 0
1(0xff8cac4c): 1
2(0xff8cac50): 2
3(0xff8cac54): 3
4(0xff8cac58): 4
5(0xff8cac5c): 5
6(0xff8cac60): 6
7(0xff8cac64): 7
8(0xff8cac68): 8
9(0xff8cac6c): 9
10(0xff8cac70): 1
11(0xff8cac74): -7557836
12(0xff8cac78): -7557984
13(0xff8cac7c): 1435443200
14(0xff8cac80): 0
15(0xff8cac84): 0
16(0xff8cac88): 0
17(0xff8cac8c): 1434052387
18(0xff8cac90): 134515248
19(0xff8cac94): 0
20(0xff8cac98): 0
21(0xff8cac9c): 1434052387
22(0xff8caca0): 1
23(0xff8caca4): -7557836
24(0xff8caca8): -7557828
25(0xff8cacac): 1432254426
26(0xff8cacb0): 1
27(0xff8cacb4): -7557836
28(0xff8cacb8): -7557932
29(0xff8cacbc): 134520132
30(0xff8cacc0): 134513420
31(0xff8cacc4): 1435443200
32(0xff8cacc8): 0
33(0xff8caccc): 0
34(0xff8cacd0): 0
35(0xff8cacd4): 346972086
36(0xff8cacd8): -29697309
37(0xff8cacdc): 0
38(0xff8cace0): 0
39(0xff8cace4): 0
40(0xff8cace8): 1
41(0xff8cacec): 134514984
42(0xff8cacf0): 0
43(0xff8cacf4): 1432277024
44(0xff8cacf8): 1434052153
45(0xff8cacfc): 1432326144
46(0xff8cad00): 1
47(0xff8cad04): 134514984
...
//The heck?! This just ends with a Runtime Error after like 200 lines.
很明显,使用他们的编译器,单个索引溢出缓冲区会导致程序进入无限循环!
现在,重申一下:我意识到我正在处理这里未定义的行为。但尽管如此,我还是想知道幕后究竟发生了什么导致了这一切。物理上执行缓冲区溢出的代码仍在执行 4 个字节的读取并将读取的任何内容写入(可能受到更好保护的)缓冲区。导致这些问题的编译器/CPU 正在做什么?
最佳答案
导致条件i < 11
的执行路径有两条正在评估中。
第一个是在初始循环迭代之前。自 i
已初始化为 0
就在检查之前,这是微不足道的事实。
第二个是在成功的循环迭代之后。由于循环迭代导致values[i]
被访问,和values
只有 10 个元素,只有 i < 10
才有效.如果i < 10
, 在 i++
之后, i < 11
也必须为真。
这是 Ideone 的编译器 (GCC) 正在检测的内容。条件没办法i < 11
除非你有一个无效的程序,否则它可能永远是错误的,因此它可以被优化掉。同时,您的编译器不会特意检查您是否有无效程序,除非您提供额外的选项告诉它这样做(例如 GCC/clang 中的 -fsanitize=undefined
)。
这是实现必须做出的权衡。他们可以支持无效程序的可理解行为,或者他们可以支持有效程序的原始速度。或者两者兼而有之。 GCC 肯定非常关注后者,至少在默认情况下是这样。
关于c++ - 未定义的行为怪癖 : reading outside a buffer causes a loop to never terminate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41902356/
我正在尝试使用一个使用 JNI 的库。 我已经尝试了开发人员提供的示例应用程序,它可以工作。所以我知道这不是库中的错误。 我认为我在导入库的过程中做错了什么: 将 .so 文件复制到我的 libs 文
使用Websphere 应用程序服务器 + Wicket 1.6我的挂载 URL 遇到一些问题。 当我调用类似于以下内容的网址时:localhost:9080/danesCooking/pies/me
我有一个应用程序在 Win2k3 VM 上的 Apache Tomcat 5.5 上运行。该应用程序提供 XML,供某些电话设备使用,作为我们 IVR 基础设施的一部分。反过来,应用程序从一些 SOA
升级到雅加达给我带来了一些问题。。我正在使用以下maven插件:。并且我使用episodal编译(有库)。突然间,我面临着以下问题:。更仔细的检查发现,XJC突然生成了以下字段:。这是它以前没有产生的
Jenkins 有一个可用于自由式构建作业的 $CAUSE 变量。 如何在工作流程中访问此内容或类似内容? 我的团队在现有临时构建的电子邮件输出中使用它。我们希望在新的基于工作流的工作中继续这样做。
错误:无法完成 Gradle 执行。 原因: Could not create parent directory for lock file C:\Program Files\Android\Andr
如何确定多个浏览器 UI 事件是否由相同的基本 UI 交互引起? 例如,用户单击和事件监听器会触发“blur”和“mousedown”事件。有没有办法确定这两个事件都是由一次用户点击引起的? 最佳答案
它可以编译,但不会从 .o 文件链接到可执行文件。我已经删除了从现在到运行良好时所做的所有更改(基本上,str_to_int 中的所有内容)。 我的代码: #include #include in
关于 Java 的 InterruptedException 有一些有趣的问题和答案。 ,例如 The Cause of InterruptedException和 Handling Interrup
我使用 android 工具 “内存监视器” 来修复内存泄漏。这很有帮助。 但是,我需要澄清一下。 有时在运行该应用程序后,分配的内存为“47MB”。当与应用交互时,它会上下移动。 然后当我点击“ca
我正在调查由于堆损坏而导致的崩溃。由于这个问题很重要并且涉及分析堆栈和转储结果,因此我决定对与崩溃相关的文件进行代码审查。 坦率地说,我对堆何时可能损坏没有深入的了解。 如果您能提出可能导致堆损坏的方
假设我们有一个名为 feature-branch 的功能分支。该分支的开发人员分支获取他们的票,然后打开一个 PR 到 feature-brach。 如果发生以下情况: 开发人员A从feature-b
两个线程同时访问fileName。 Set If 0 使死锁。但如果 1 一切顺利。 那么是什么导致了这种情况? 最佳答案 确保您没有在主线程上同步调用 +[PHAssetResource asset
不幸的是,我还不是正则表达式专家,因此遇到了以下问题:假设我有一个包含多个链式异常的 Java 堆栈跟踪,我想要达到的是提取以“Caused by”开头的最后一行。 javax.servlet.Ser
我确信这是我所缺少的非常简单的东西。我使用 makeKeyAndOrderFront: 打开一个窗口,它第一次工作。当我关闭窗口并尝试再次打开它时,它退出并给出错误EXC_BAD_ACCESS。我的代
我刚刚探索了 Rank2Types 和 RankNTypes,试图熟悉它们。但我不明白为什么以下不起作用。 g :: (forall a. forall b. a -> b) -> x -> y ->
我想验证输入是否严格是由 10-16 个字符长组成的数字。根据用户输入值,我将在输入字段下方显示一条消息。问题是,当我去使用时为了帮助完成此任务,它会导致应用程序抛出异常。 我是 JSF 新手,我很难
许多内置的 Java 异常无法接受“原因”。有什么方法可以为这些异常指定原因吗? 我希望能够链接异常,就像这个 InterruptedException 示例一样: try{ //thread
我创建了一个 JSP Mysql 和 Bootstrap Crud 应用程序。当我单击“更新”按钮时,将调用函数 validation() 来更新所有字段,在成功更新后,它将重定向到另一个 JSP 页
我看到了奇怪的情况:在我的 Android 应用程序代码中使用类似这样的东西时我没有收到任何错误: @Override public void onBackPressed() { if
我是一名优秀的程序员,十分优秀!