c++的do引用占用内存
C++ do references occupy memory
我已经读到,引用只是一个别名存在于符号表中的变量。考虑下面的代码
int main()
{
int y = 6;
int &z = y;
int k = 43;
test(2,y,5,78);
cout << &y << "n";
cout << &z << "n";
cout << &k << "n";
}
void test(int a,int & x, int g, int h)
{
cout << &a << "n";
cout << &x << "n";
cout << &g << "n";
cout << &h << "n";
}
对于输出,我得到
0039F740
0039F848
0039F748
0039F74C
0039F848
0039F848
0039F830
如果引用不占用堆栈中的内存,为什么内存被偏移?如。在函数测试中,局部变量a在0039F740,而g在0039F748。我不是应该在0039F744吗?
谁能详细解释一下吗?
你的函数有四个参数
每个参数必须传递给函数。
其中一个形参是引用这一事实并不改变这一基本事实。您看到的额外空间是函数的引用形参。
在这个上下文中,引用实际上只是一个伪装的指针。当你在局部作用域中有一个引用引用一个局部作用域中的对象时,大多数c++编译器实际上会把它优化掉,这样引用就不会占用任何实际的内存。但是函数调用是一个全新的游戏。函数期望接收到某个对象的引用。函数不能通过心灵感应知道传递给它的引用是什么。调用函数的对象负责提供引用形参。不用说,需要几个字节来传递该信息,即作为引用传递的对象的地址(我最近提到过指针吗?)
如果函数是用static
作用域声明的(没有外部链接),并且选择了一个足够积极的优化级别进行编译,那么c++编译器将内联函数调用,并且能够优化引用参数。
但是声明带有外部链接的函数通常会导致编译器懒得尝试内联函数调用。它将继续并生成一个完整的独立函数,该函数期望具有它有权使用的每个参数。
用更一般的方式回答你的问题:c++标准不要求引用必须占用内存,但也不要求它们不应该占用内存。c++编译器可以自由地以任何方式编译代码,只要结果是正确的,并且符合预期。如果在特定情况下,c++编译器找出了如何优化一个引用,使其实际上不作为独立的对象"存在",那么它可以自由地这样做。但这不是必需的
引用比"符号表中其他东西的别名"要复杂得多。事实上,这个定义通常并不适用。例如,引用形参不能只是别名为"符号表中的其他内容",因为那样会防止调用带有多个不同实参值的函数。
标准没有说明应该怎么做,但是引用的典型实现是只使用指针。如果有int& x
,则x
返回*(pointer)
, &x
返回(pointer)
。指针确实占用内存,但是没有定义良好的c++操作会获知返回引用的指针的存储位置。
请注意,除非您需要通过自动存储("在堆栈上")获取对象的地址,否则编译器不需要实际将其放入堆栈中。它可以完全存在于寄存器中,也可以完全被优化掉。例如,使用这个函数:
int foo(int a, int b) { return a + b; }
在使用System V调用约定的x86_64上,a
在rdi寄存器中传递,b
在rsi
寄存器中传递,结果在rax
中计算,并且函数不需要接触堆栈中的任何值。
我认为这与基指针改变有关
如果编译器只是想将它们作为别名实现,那么无论何时函数使用引用,我们都需要将其替换为原始地址,但由于该引用来自堆栈中的函数,因此该地址将具有(Basepointer - offset)的形式。但是在进入这个新函数(即test)时,我们在开始时改变了BP,所以它不再可能了,所以我们需要实现这个引用一个指针,这占用了内存。
- 对具有动态分配的内存和析构函数的类对象的引用
- 多个"常量引用"变量可以共享同一个内存吗?
- C++ 在类中使用常量引用文本时 O2 内存泄漏
- 常量引用的内存位置
- 引用释放的内存是未定义的行为吗?
- 为什么"std::uninitialized_copy"通常取消对未初始化内存的迭代器的引用不是未定
- 垃圾回收正在移动内存中被引用的对象,破坏Unreal4引擎中的引用
- X 处的指令引用了 Y 处的内存.内存无法读取
- 按引用传递和动态内存分配之间的区别是什么
- 如果引用应该保留,不删除析构函数中的指针会导致内存泄漏吗?
- 内存引用发送到双指针
- 可变引用以及指针如何与内存相互作用
- 通过引用 cpp 中的变量占用的内存
- C++中引用变量的内存?
- 来自引用指针的内存泄漏
- 在闭包中,如何通过存储在内存中的指针或引用类型捕获可变性或用现代函数式语言进行处理?
- Swift 3 引用类型和内存管理
- 数组是通过引用传递的,但是如果我只传递未存储在内存中的数组的值,会发生什么
- cpp 中的引用如何具有相同的内存地址
- 内存引用范围问题:变量值被重置,如何将值分配给LPCWSTR