关于Pointers与References内存存储及函数传参的技术问询
C++指针与引用的内存存储机制(x64 MSVC 14.35.32215)
示例1的内存存储细节
int a = 1; int *b = new int{ 5 }; int &c = a;
- 变量
a:存储在栈上,a本身就是一块4字节的内存空间,其内存地址对应的内容就是数值1——不存在“变量和值分属不同内存块”的情况,变量的内存块就是用来存储它的值的载体。 - 指针
b:b是栈上的指针变量(x64下占8字节),它存储的是通过new在堆上分配的int类型内存的地址。堆上的这块4字节内存里存储着数值5,栈上的b仅保存指向该堆内存的地址,不会存储5本身。 - 引用
c:从C++标准定义来看,引用是变量的别名,标准不强制要求它占用内存。但在x64 MSVC 14.35中:- 开启编译器优化(默认Release模式)时,
c会被编译期直接替换为a的别名,不会占用额外内存,所有对c的操作都会直接映射到a的内存。 - 关闭优化(Debug模式)时,编译器可能会用指针实现引用——此时
c会在栈上占用8字节内存,存储a的地址,但语法上仍保持引用的特性(不能重新绑定、无需解引用)。
- 开启编译器优化(默认Release模式)时,
示例2的函数参数内存机制
void Func1(int a) { /* code */ } void Func2(int *b) { /* code */ } void Func3(int &c) { /* code */ }
Func1的参数a:值传递,调用函数时,实参的数值会被复制到函数栈帧的新内存块中(x64下占4字节),函数内对a的修改不会影响外部实参。Func2的参数b:指针传递,调用时仅会将实参指针的地址值(8字节)复制到函数栈帧中,指针指向的堆(或栈)内存不会被复制。函数内通过*b访问的是原指针指向的内存,修改*b会直接改变目标内存的值,但修改b本身(比如让它指向其他地址)不会影响外部的指针变量。Func3的参数c:引用传递,从语法上看是实参的别名,实际在x64 MSVC中的实现:- 开启优化时,编译器会直接使用实参的内存地址,不会在函数栈帧中分配额外空间,函数内对
c的操作等同于直接操作外部实参。 - 关闭优化时,编译器可能会用指针实现——栈帧中分配8字节存储实参的地址,但语法上仍以引用的方式使用,无需手动解引用。无论哪种实现,都不会复制实参的内容,函数直接操作实参的原始内存(实参可在栈或堆上,并非仅堆)。
- 开启优化时,编译器会直接使用实参的内存地址,不会在函数栈帧中分配额外空间,函数内对
内容的提问来源于stack exchange,提问作者fzyier
相关产品推荐
相关产品推荐

