C++地址(学指针前必须掌握)

单个变量的地址:

在C++中,地址是指内存中的位置。每个变量在内存中都有一个唯一的地址。通过地址,我们可以读取和修改变量的值,也可以创建指向对象的指针。

地址是一个整数值,用十六进制表示。地址的大小取决于操作系统的位数,例如32位操作系统中的地址通常是32位(即4个字节,8位十六进制数),64位操作系统中的地址通常是64位。可以使用取地址运算符(&)来获取变量的地址。例如,如果有一个整数变量x,可以使用"&x"来获取x的地址,当&作用于一个对象上时,它返回了该对象的地址

	int x;
	cout << &x << endl;

细节来了!对照代码和图片,这里会输出4个地址吗?只会输出第一个地址0x1000,因为可以通过int是4个字节+第一个地址,可以计算得到由0x1000、0x1001、0x1002、0x1003共同组成了变量x的储存空间。

数组的地址:

在C++中,一维数组可以看作是一系列相同类型的元素的集合。图中我们申请了一个长度为4的整型数组,计算机给a[4]分配了快连续的区间0x1000~0x1015,其中数组首地址可以用过&a[0]来获取,c++还特别规定了数组名就是数组的首地。有关一维、二维数组的指针应用,请同学们移步C++指针类型的概念及基本应用。

内存地址空间(选读):

内容比较多,请同学们结合图片来食用。

栈是一种动态分配内存的区域,用于存储函数的局部变量和函数调用的上下文信息。

当一个函数被调用时,栈会为该函数分配一块内存空间,用于存储函数的局部变量和函数调用的上下文。局部变量是在函数内部定义的变量,它们的生命周期与函数的执行周期相对应。当函数调用结束时,栈会自动释放该函数的内存空间,包括其中的局部变量。

栈中的内存空间是按照先进后出的原则进行分配和释放的,每当一个函数被调用时,栈会将函数的局部变量和函数调用的上下文信息入栈(分配内存),当函数调用结束时,栈会将这些信息出栈(释放内存)。

由于栈的自动管理特性,局部变量的分配和释放速度相对较快,适合存储函数内部临时使用的数据。然而,需要注意的是,栈的大小是有限的,过多的局部变量或过深的函数调用可能导致栈溢出的错误。

注意,全局变量、静态变量和常量等通常存储在另外的内存区域。这些变量的生命周期不依赖于函数的执行,它们在程序运行期间一直存在。

堆是一种动态分配内存的区域,用于存储程序的动态分配数据,如使用newmalloc函数分配的内存。堆的大小在程序运行时是可变的,通常较大,且需要手动管理(必须手动释放分配过的内存)。堆中的内存分配和释放由程序员负责,需要显式地调用deletefree函数来释放已分配的内存。由于堆的动态管理特性,它的分配和释放速度相对较慢。

因此,从大小上来说,堆的大小通常比栈大。栈的大小是由操作系统或编译器预先分配的,而堆的大小可以根据程序的需要进行动态调整。

#include <bits/stdc++.h>
using namespace std;
//常量区
const int N=100;
//全局数据区
int a,b,c;
int main() {
	//栈
	int x,y,z;
	//堆
	int *p = new int[3]; 

	printf("---常量区地址分配情况---\n"); 
	printf("常量N的地址:    %p\n", &N);
	
	printf("---全局数据区地址分配情况---\n"); 
	printf("全局变量a的地址: %p\n", &a); 
	printf("全局变量b的地址:%p\n", &b); 
	printf("全局变量c的地址:%p\n", &c); 

	printf("---堆区地址分配情况---\n"); 
	printf("    p[0]的地址: %p\n", p); 
	printf("    p[1]的地址: %p\n", p+1); 
	printf("    p[2]的地址: %p\n", p+2); 
	
	printf("---栈区地址分配情况---\n"); 
	printf("局部变量x的地址: %p\n", &x); 
	printf("局部变量y的地址:%p\n", &y); 
	printf("局部变量z的地址:%p\n", &z); 
	
	//需手动释放堆区空间
	delete[] p;
	return 0;
}

输出:

---常量区地址分配情况---
常量N的地址:    000000000048813c
---全局数据区地址分配情况---
全局变量a的地址: 00000000004a7030
全局变量b的地址:00000000004a7034
全局变量c的地址:00000000004a7038
---堆区地址分配情况---
    p[0]的地址: 00000000001b1520
    p[1]的地址: 00000000001b1524
    p[2]的地址: 00000000001b1528
---栈区地址分配情况---
局部变量x的地址: 00000000006ffe14
局部变量y的地址:00000000006ffe10
局部变量z的地址:00000000006ffe0c

 最后讲一讲很少有人提起的两块灰色区域:

保留区域是用来存储操作系统保留的内存空间,通常用于存放操作系统内核、驱动程序和其他系统级的数据结构。这些区域通常是不可被普通用户程序访问的,用于维护系统的正常运行和管理。

#include <stdio.h>

int main() {
    int *reserved_memory = (int *)0x80000000; // 以0x80000000地址为例,这是一个保留区域的地址
    *reserved_memory = 10; // 尝试写入保留区域的内存,通常会导致段错误或者其他异常
    return 0;
}

通过内核空间,操作系统可以提供各种系统服务和功能,如进程管理、文件系统、网络通信、设备驱动等。用户程序通过系统调用接口来请求内核提供的服务,内核在内核空间中进行相应的处理,然后返回结果给用户程序。由于内核空间拥有更高的权限和更广泛的操作权限,因此内核代码的编写和修改需要非常谨慎,以确保系统的稳定性和安全性。

  • 14
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值