在c/c++中如何确定使用哪个内存块?

How is it determined which memory block to use in c/c++?

这是我写的代码:

#include <iostream>
using namespace std;

int main() {
    int x[3] = {30,31,32}, y[3] = {40,41,42}, z[3] = {50,51,52};

    for (int i=0; i < 3; i++) {
        cout << *(x+i) << endl;
        cout << *(x-(3-i)) << endl;
        cout << *(x-(6-i)) << endl;
    }
    cout << endl;
    for (int i=0; i < 3; i++) { 
        cout << (long int)&x[i] << endl; // address of x
    }
    cout << endl;
    for (int i=0; i < 3; i++) {
        cout << (long int)&y[i] << endl; // address of y
    }
    cout << endl;
    for (int i=0; i < 3; i++) {
        cout << (long int)&z[i] << endl; // address of z
    }
}

输出如下:

30
40
50
31
41
51
32
42
52

140701886846268
140701886846272
140701886846276

140701886846256
140701886846260
140701886846264

140701886846244
140701886846248
140701886846252

这里可以看到最后声明的数组占用最前面的内存地址,倒数第二个占用最后一个之后的内存地址,依此类推。

Here you can see the array which was declared at last takes the foremost memory address and second last takes memory address after the last one and so on.

不,这不是正在发生的事情。该程序具有 未定义的行为 ,因为对于 i 的不同值,您超出了表达式 *(x-(3-i))*(x-(6-i)) 的数组边界。

Undefined behavior means anything1 can happen including but not limited to the program giving your expected output. But never rely(or make conclusions based) on the output of a program that has undefined behavior. The program may just crash.

所以您看到(也许看到)的输出是未定义行为的结果。正如我所说,不要依赖具有 UB 的程序的输出。程序可能会崩溃。

因此,使程序正确的第一步是删除 UB。 然后并且只有那时您可以开始对程序的输出进行推理。在你的情况下,这意味着你必须确保你没有超出数组的范围。


1有关未定义行为的技术上更准确的定义,请参阅 this 其中提到:没有对程序行为的限制.