为什么这段代码表现得很奇怪?

发布于 2025-01-07 05:27:08 字数 855 浏览 0 评论 0原文

我在 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

因此,如果堆栈解释正确,则在这种情况下也应该修改其中一个值,对吗?事实并非如此。

I have this code in C++ which is giving weird output:

#include<iostream>
using namespace std;
int main(){
    int r[15]={0};
    int n = 5;
    r[15]=20;
    cout<<n;    
}

The output should obviously be 5, but it gives me 20. Now I know r[15] is out of bounds. This code should've thrown an exception for trying to access r[15], shouldn't it? However, it compiles normally with g++ and giving wrong output. I'm not able to figure out what's causing this anomaly. Can anyone help?

Just FYI, this code is just a sample, I had to figure this bug out from a larger code which took me a lot of time which, otherwise, could've been saved if an exception was thrown.

Update:
I checked the following code:

#include<iostream>
using namespace std;
int main(){
    int n = 5;
    int r[15]={0};
    r[15]=20;
    cout<<n;
}

Output:
20

I checked the following code too:

#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

So if the stack explanation is correct, either of the values should've been modified in this case too, right? It doesn't.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

送你一个梦 2025-01-14 05:27:08

由于 r 是一个包含 15 个元素的数组,因此 r[14] 是最后一个元素。因此 r[15]=20; 是未定义的行为。 C++ 不进行边界检查,因此在处理普通数组时不会出现异常。

在您的情况下,r[15]=20恰好覆盖存储n的精确位置处的堆栈。

Since r is a 15-element array, r[14] is the last element. Therefore r[15]=20; is undefined behavior. C++ doesn't do bounds checking so you won't get exceptions when dealing with plain arrays.

In your case r[15]=20 happens to overwrite the stack at the precise location where n is stored.

遥远的绿洲 2025-01-14 05:27:08

现在我知道r[15]超出了范围。此代码应该在尝试访问 r[15] 时引发异常,不是吗?

除非您使用某种检查库,否则不会。 C(和 C++)非常接近机器,因此您可能会遇到这种情况。 (这是它们力量的一部分。)某些编译器上有编译器标志,它们会插入边界检查(以运行时成本),但 gcc 不会这样做(您可以找到补丁集将其添加为一个功能,虽然我认为只适用于 C)。

那里发生的事情(显然)是您的 n 变量在 r 数组的 15 个槽之后立即结束在堆栈上:

+-------+
| r[0]  |
| r[1]  |
| r[2]  |
...
| r[13] |
| r[14] |
| n     |
+-------+

...因此写入您的输出- of-bounds 条目 r[15] 最终会覆盖它(在您的特定情况下;这不是您可以或不应该指望的行为,堆栈上的事物的顺序未定义为由它们在源中声明的顺序,也可能不是)。

Now I know r[15] is out of bounds. This code should've thrown an exception for trying to access r[15], shouldn't it?

Not unless you're using some kind of checking library, no. C (and C++) are very close to the machine and so you can get yourself in this kind of situation. (That's part of their power.) There are compiler flags on some compilers that will insert bounds checking (at a runtime cost), but gcc doesn't do it (you can find patchsets to add it as a feature, though I think only for C).

What's happened there (apparently) is that your n variable ends up on the stack immediately after the 15 slots of the r array:

+-------+
| r[0]  |
| r[1]  |
| r[2]  |
...
| r[13] |
| r[14] |
| n     |
+-------+

...and so writing to your out-of-bounds entry r[15] ends up overwriting it (in your particular case; that's not behavior you can or should count on, the order of things on the stack is not defined as being determined by the order in which they're declared in the source, and may well not be).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文