C++ 堆栈内存、引用和指针详解
创作时间:
作者:
@小白创作中心
C++ 堆栈内存、引用和指针详解
引用
CSDN
1.
https://blog.csdn.net/weixin_40653140/article/details/137168242
C++ 堆栈内存、引用和指针
在学习C++编程时,堆栈内存、引用和指针是三个非常重要的概念。它们不仅关系到程序的内存管理,还影响着程序的性能和安全性。本文将详细介绍这些概念及其相互关系。
一、堆和栈内存
在学习引用和指针之前,先要了解堆和栈内存的相关概念。
1.1、内存地址
一个打印内存地址的示例:(先声明变量,再用&获取地址)
#include <iostream>
using namespace std;
int main () {
int int_value = 1;
double double_value = 0.0;
char array_value[10];
cout << "address of int_value: " << &int_value << endl;
cout << "address of double_value: " << &double_value << endl;
cout << "address of array_value: " << &array_value << endl;
cout << "array_value[1]:" << &array_value + 1 << endl;
return 0;
}
代码解析:
- 每一个变量都有一个内存位置,内存地址表示这个位置;
- 用
&符号可以获取变量地址 &array_value + 1不是值 +1,而是位置再 +1(下一个字节)&array_value取的是 array_value[0] 的地址- 代码中获取的都是栈内存(没用 new 和 delete)
- 上面每次运行的结果都不一定相同,因为地址是操作系统分配的。
1.2、内存布局
电脑可以有多个进程,这是其中一个进程的内存布局图。
可以看到有两个重点:
- static memory layout:存放全局或者静态数据
- dynamic memory layout:程序使用的内存-> stack(栈内存)+ heap(堆内存)
堆栈内存的对比:
使用场景举例:
- 一些实时的变量,一般就会在栈内存中。因为不超过几十MB。
- 如果是体积很大的数据(点云或者图像),就需要在堆内存申请。
堆内存用关键字new来创建,用关键字delete来释放
需要用栈内存上的一个变量(指针)来表示地址,来指向堆内存的位置并对堆内存上的对象进行管理
二、指针 - 管理变量地址的工具
2.1、指针基本总结
定义:指针(pointer)是一种特殊的变量,其值为内存地址。
作用:通过指针可以直接访问和操作内存中的数据。
声明语法:Type pointer_ame;,其中Type是指针所指向的数据类型,pointer_pame是指针变量名。
初始化:可以将指针初始化为某个变量的地址,也可以将其初始化为nullptr(空指针)。
取地址操作符:&,用于获取变量的地址。
解引用操作符:,用于访问指针所指向的数据。
长度:不管 Type 是什么,指针长度都是一样,都是一个代表内存地址的长的十六进制数。
示例代码:
#include <iostream>
using namespace std;
int main () {
int var = 20; // 实际变量的声明
int *ip; // 指针变量的声明
ip = &var; // 在指针变量中存储 var 的地址
cout << "Value of var variable: ";
cout << var << endl; // 输出在指针变量中存储的地址
cout << "Address stored in ip variable: ";
cout << ip << endl; // 访问指针中地址的值
cout << "Value of *ip variable: ";
cout << *ip << endl;
return 0;
}
2.2、指针的价值
在 C++ 中,指针的存在是为了提供更灵活的变量操作和内存管理方式:
- 内存访问和操作:指针允许程序直接访问和操作内存地址。这对于底层编程(如操作系统或嵌入式系统开发)非常重要,因为它们需要精确控制内存和硬件。
- 效率提升:通过指针,函数可以直接操作原始数据而不是其副本,这样可以避免不必要的数据复制,特别是对大型数据对象,可以显著提高程序的效率。
- 动态内存分配:指针是动态内存分配的基础。
- 实现数据结构:指针对于实现各种数据结构(如链表、树、图等)是必不可少的。
- 多态和接口:在面向对象编程中,通过基类指针或引用,可以访问派生类的对象,实现多态行为。
- 批量传递:C++函数默认只能返回一个值。通过使用指针,函数可以修改传入的变量,从而实现返
回多个值的效果。
三、引用
概念:
引用(reference)是一个别名,它提供了对已存在变量的另一个名称。
- 声明语法:type& refName = var;,其中type是引用所引用的类型,refName是引用的名称,var是被引用的变量。
- 作用:ref 就是 y 的引用,意味着 ref 和 y引用了相同的内存地址,对其中一个的修改会影响到另一个。比如下面的例子, a 和 b 的地址完全一样。
int a = 111;
int& b = a;
cout << "b"<< b << endl;
cout << "address"<< &a <<" "<< &b << endl;
特性:
- 一旦初始化,不能重新绑定:引用一旦与某个变量绑定,就不能再改变其指向的变量。
-不占用额外内存:引用不占用额外的内存空间,它只是变量的一个别名。
-引用作为函数参数:引用可以作为函数的参数,通过引用参数可以直接修改函数外部的变量。
应用场景:
- 函数返回值:函数可以返回引用类型,使得可以返回函数内部的局部变量或临时对象。
-函数参数传递:通过引用参数可以避免函数参数的拷贝,提高程序的效率。
-函数返回值赋值:可以将函数返回的引用直接赋值给其他变量,提高代码的简洁性和可读性。
四、引用和指针的关系
- 指针可以为空(nullptr);但引用不能,在定义时必须绑定一个变量。
- 指针和引用都是C++中非常有用的工具,但需要根据具体情况选择使用哪种。在大多数情况下,引用更安全、更易读,而指针则更灵活、更强大。
- 引用实际上就是用指针实现的:编译器将引用转换为对应的指针操作,并在编译过程中进行优化和替
换。这样做的目的是为了让引用在语法上与指针有所区别,同时在底层实现上与指针相近,以保证引
用的高效性和易用性。 - 几乎只有C/C++提供最直接的内存管理机制:指针,而其他语言不会让用户直接用指针管理、操作内存。
- 指针(包括引用)的优势在于提供了直接内存访问、动态内存分配、高效数据传递、与硬件直接交互
的优势,但它也带来了内存错误、复杂性和安全性等挑战。
热门推荐
探访文化遗存现今的模样丨八陡老街:岁月更替中焕发蓬勃生机
李姓男孩双胞胎起名的技巧与建议
新手钓鱼:鱼竿选长还是选短?
双十一后,用这些伤感语录治愈你的心
精选伤感语录:在伤感中寻找治愈
2025年全球最火的旅行目的地,就在家门口
WTT中国大满贯门票被炒至近2万元:一票难求背后的商业逻辑
正月初五迎关帝:千年信仰与文化传承
剑阁县:丹参产业助力乡村振兴跑出“加速度”
苏轼的爱情诗篇:从《江城子》到《饮湖上初晴后雨》
苏轼妻子们的那些事儿,你了解多少?
王弗:苏轼背后的女人,她的智慧你了解吗?
苏轼与王弗:一首《江城子》道尽十年生死两茫茫
苏轼笔下的两位妻子:谁更得宠?
318国道:探访雅鲁藏布江最美自驾游
青藏高原上的神秘气候:雅鲁藏布江揭秘
探秘雅鲁藏布大峡谷:地球上的最后秘境
揭秘雅鲁藏布江畔的史前文明:从石器工厂到天文记录
高原“胡子鱼”的守护者:雅鲁藏布江鱼类保护行动
揭秘珠穆朗玛峰:板块碰撞与河流袭夺共同塑造的世界之巅
克什米尔喜马拉雅保护区:生物多样性的守护者
百年流变:“列夫·托尔斯泰学”在中国
那代创业者给我们的激励与启示
白洋淀诗歌群——北何庄村、寨南村知青点
阳光米易:一座没有冬天的“内地三亚”
广东省旅游发展大会“强信号” 加快建设旅游强省 释放“旅游兴百业旺”效应
扬州旅游攻略:美食与文化体验指南
金寨县沙河乡:灵芝菇种植助力乡村振兴
广饶县荣泰合作社:灵芝菇种植的环保新趋势
非遗融环保,点燃指尖上的风景!