为什么这段代码表现得很奇怪
Why does this piece of code behave weird?
我在C++中有这样的代码,它给出了奇怪的输出:
#include<iostream>
using namespace std;
int main(){
int r[15]={0};
int n = 5;
r[15]=20;
cout<<n;
}
输出显然应该是5,但它给了我20。现在我知道r[15]出界了。这段代码应该在尝试访问r[15]时抛出一个异常,不是吗?然而,它使用g++进行正常编译,并给出错误的输出。我不知道是什么导致了这种异常现象。有人能帮忙吗?
仅供参考,这段代码只是一个示例,我必须从一个更大的代码中找出这个错误,这花了我很多时间,否则,如果抛出异常,这些时间本可以保存。
更新:我检查了以下代码:
#include<iostream>
using namespace std;
int main(){
int n = 5;
int r[15]={0};
r[15]=20;
cout<<n;
}
Output:
20
我也检查了以下代码:
#include<iostream>
using namespace std;
int main(){
int n = 5;
int a=5;
int r[15]={0};
r[15]=20;
cout<<n<<endl<<a;
}
Output:
5
5
因此,如果堆栈的解释是正确的,那么在这种情况下,其中任何一个值都应该被修改,对吧?事实并非如此。
由于r是一个15元素的数组,r[14]
是最后一个元素。因此r[15]=20;
是未定义的行为。C++不进行边界检查,所以在处理纯数组时不会出现异常。
在您的情况下,r[15]=20
恰好在存储n
的精确位置覆盖堆栈。
现在我知道
r[15]
是越界的。这段代码应该在尝试访问r[15]
时引发异常,不是吗?
除非你使用某种检查库,否则不会。C(和C++)非常接近机器,所以你可以陷入这种情况。(这是它们的一部分功能。)有些编译器上有编译器标志,可以插入边界检查(以运行时为代价),但gcc
不这样做(你可以找到补丁集将其作为一种功能添加,尽管我认为只适用于C)。
那里发生的事情(显然)是,您的n
变量在r
数组的15个插槽之后立即出现在堆栈上:
+-------+|r[0]||r[1]||r[2]|。。。|r[13]||r[14]||n|+-------+
因此,写入越界条目r[15]
最终会覆盖它(在您的特定情况下,这不是您可以或应该依赖的行为,堆栈上的事物的顺序并不是由它们在源中声明的顺序决定的,很可能是而不是)。
相关文章:
- 为什么我的C++代码在以下打印链表的代码片段中显示分段错误?
- 使用链表.为什么我的插入功能不起作用?
- 为什么我在链表中插入的代码没有得到任何输出?
- IBM Rhapsody c++ 代码生成 - 为什么总是在状态图周围放置一个活动状态
- 此代码,为什么必须显示不确定的行为
- 如果C++编译为机器代码,为什么我们需要安装"运行时"?
- 为什么下面的使用链表实现线性队列的代码返回垃圾值然后崩溃
- 为什么我的代码无法在二叉搜索树中正确执行预购表单?
- 我正在尝试在Visual Studio 2013中编写我的第一个"Hello World"代码。为什么我会收到"IntelliSense: no operator message"和"error C2
- 为什么这个从链表中删除节点的代码不起作用?
- 如果我用代码块编译代码,为什么我的代码运行速度更快
- C 为什么我的代码将注册表密钥放在错误的目录中
- 释放构建仍然允许逐步通行代码,为什么
- 为什么在此 C 代码中将字母表拆分为多个范围?
- 将链接哈希表初始化为 NULL。获取"lvalue required as left operand of assignment"错误。为什么?这是我的代码:
- C++中的记忆代码:为什么它不起作用?
- 根据代码表构建一个huffman树
- 代码厨师 Q - 为什么我会收到"Wrong Answer"错误
- 在霍夫曼压缩后将代码表存储在压缩文件中,并从此表构建用于解压缩的树
- 代码::BLOCKS-为什么路径不正确