这是一道百度的笔试题

问:关于下面的程序输出为:

  • A:1
  • B:2
  • C:3
  • D:编译无法通过
#include <iostream>
using namespace std;

void test(int a,int b,int c){
    int *p = &b;
    cout << *(p-1) << endl;
}

int main(){
    test(1,2,3);
    return 0;
}

正确答案是…

C

如果和你想的一样,那说明你已经掌握了这个知识点了。

第一眼看本来想选 D 的(我是个呆瓜🐽),后来想了一下(就是想了一下而已),决定选 A。

我对这道题还是比较好奇,于是笔试完用 OnlineGBD 敲了一下。

结果竟然是…!!!

image-20220413012816216

一时之间不知道为什么,并且表示很吃惊,于是和同学讨论一下。

image-20220413012958685

让我更是震惊,难道天底下只有我一个呆瓜吗😂

image-20220413013118413

又简单聊几句勾起了我大脑深处尘封已久的对于知识的记忆。我想起了栈区地址和堆区地址生长方向的问题,但是记不清楚栈区是低地址向高地址生长还是高地址向低地址生长。又联想前大家总是说压栈,难道是低地址向高地址生长?可是和输出结果不相符啊。

于是简单测试一下。

image-20220413014231008

结论很显然:

栈区向低地址生长,堆区向高地址生长

更多测试

既然已经测试到这了,干脆就复习的全一些,把各种变量都测试一下。

#include <iostream>
using namespace std;

static int p = 5;
static int q = 6;

const int m = 7;
const int n = 8;

void test(int a,int b,int c){
    
    static int i = 2;
    static int j = 3;
    
    const int s = 4;
    const int t = 5;
    
    int* x = new int(a);
    int* y = new int(b);
    int* z = new int(c);
    
    cout << "栈区地址:" << endl;
    cout << &a << endl << &b << endl << &c << endl;
    
    cout << "堆区地址:" << endl;
    cout << &x << endl << &y << endl << &z << endl;
    
    cout << "全局Const常量:" << endl;
    cout << &m << endl << &n << endl;
    
    cout << "局部const常量:" << endl;
    cout << &s << endl << &t << endl;
    
    cout << "全局静态变量:" << endl;
    cout << &p << endl << &q << endl;
    
    cout << "局部静态变量:" << endl;
    cout << &i << endl << &j << endl;
    
    cout << "字符串常量:" << endl;
    cout << &"abc" << endl << &"efg" << endl;
    
}

int main()
{
    test(1,2,3);

    return 0;
}

代码的运行结果如下:

栈区地址:
0x7ffc3e31b75c
0x7ffc3e31b758
0x7ffc3e31b754
堆区地址:
0x7ffc3e31b770
0x7ffc3e31b778
0x7ffc3e31b780
全局Const常量:
0x561341be9008
0x561341be900c
局部const常量:
0x7ffc3e31b768
0x7ffc3e31b76c
全局静态变量:
0x561341beb010
0x561341beb014
局部静态变量:
0x561341beb018
0x561341beb01c
字符串常量:
0x561341be9093
0x561341be9097

可以得到几个基本结论:

  1. 栈区地址向下生长
  2. 堆区地址向上生长
  3. 局部进来变量和全局静态变量是放在一起的
  4. 字符串常量、静态变量和全局 const 常量处于整个内存空间的低地址,其余处于高地址。

由于局部 const 常量的生长方向是向上的,因此怀疑其可能存放在堆区(网上说其存放在栈区)。

总结

C/C++中内存分5大区:栈,堆,全局/静态存储区,常量存储区,代码区

neicunfenqu

Code Segment 代码区也称Text Segment,存放可执行程序的机器码。

Data Segment 存放已初始化的全局和静态变量, 常量数据(如字符串常量)。

BSS(Block started by symbol) 存放未初始化的全局和静态变量。(默认设为0)

Heap(堆) 从低地址向高地址增长。容量大于栈,程序中动态分配的内存在此区域。

Stack 栈从高地址向低地址增长。由编译器自动管理分配。程序中的局部变量、函数参数值、返回变量等存在此区域。