数据的存储方式

数据类型有很多种,有临时变量,也有静态类型,还有const修饰的常变量类型,等等。这么多钟不同的数据类型,每种数据类型想要完成的功能也有所不同,计算机该如何对于这些不同的数据类型进行管理呢?

如果一股脑将这些数据都放在一块,必然会引起很多问题,存储数据确实很轻松,但想用到其中某个数据呢,从里面找数据会非常麻烦

对此,计算机会根据不同的数据类型将他们存在不同的空间里

首先是临时变量(非静态局部变量),我们都熟知它是存在栈区的,另外,存在于栈区的还有函数的参数以及函数的返回值。

栈区地址的存储规则是,向下增长,所以这里可以看到,先定义的a变量的地址比后定义的b的地址更大。

并且,存储在栈区上的数据一旦出了作用域会立马销毁,如下代码是说明这条规则的有力证据:

当我们不希望某个数据被修改时,可能会在前面加上const修饰,将它定义为常变量,那这种数据又是存在哪里

常变量,难道真的存在于常量区?

错,尽管常变量确实具有常属性,但它的本质还是变量,因为常变量虽然不能直接被修改,但还是能够间接被修改,所以它应该存在于栈区。

接下来探讨静态变量的存储。静态变量顾名思义存在于静态区(数据段)。

此外,全局变量也是存在于静态区,其实也不难理解,静态变量本身就具有全局属性

下面来看这段代码:

int _a = 1;
void Test3()
{
	static int a = 1;
	static int b = 0;
	cout << &_a << endl;
	cout << &a << endl;
	cout << &b << endl;

}
int _b = 1;

int main()
{
	Test3();
	cout << &_a << endl;
	cout << &_b << endl;
	return 0;
}

果然,他们的地址如此相近,虽然不能直接得出他们就一定存在一块空间,但这也是一种体现.

当我们向内存主动申请空间的时候,动态开辟的内存无疑是在堆这个区域内申请的,与栈区不同,堆里面的空间不会自动清理,需要我们主动释放,否则将会导致内存泄漏。(动态内存的管理详见动态内存管理)。

堆区的地址是可以向上增长的。

接着来看下面这个问题:

 void Test()
 {
    int* ptr = (int*)malloc(4*sizeof(int));
 }

 这里的ptr存在哪里?*ptr又存在哪里?

毋庸置疑,*ptr是ptr指向的内容,是malloc申请出来的空间,*ptr肯定是在堆区。

而ptr只是一个指针变量,它不是申请出来的空间,当然就存储在栈区。

最后就是常量区,主要的存储对象有可执行的代码/只读常量,所有不能通过直接或者间接被修改的,都是常量,存在于常量区。

比如,1,'a' ,1.1 ,"abcd" 等等都是常量。

如下nums,ch1,以及ptr都存在哪里呢?

void Test4()
{
	int nums[5] = { 1, 2, 3, 4};
	char ch1[] = "hello world";
	char *ptr = "abcd";
}

 数组名表示首元素地址,nums和ch1分别表示的是1和'h'的地址,而ptr也是指向了"abcd"的首元素地址,可是打印出来的ptr地址却截然不同?

其实这里的nums和ch1并没有直接指向1和'h'的地址,直接用数组+方括号初始化,中间会先做一次拷贝,在栈区创建一个临时数组后,将常量区上的内容拷贝到这个临时数组里面,最后让nums和ch1指向这个数组,所以nums和ch1一定存在栈区上。哪怕就算是*nums和*ch1,他们也都存在于栈区。而ptr就没有那些步骤,直接就指向了静态区里面的"abcd",所以ptr里面存的地址就一定是一个静态区的地址。

另外,还有一个叫做内核空间的区域和一个叫做内存映射段的区域

内核空间定义:内核空间是操作系统内核运行的区域,它包括了操作系统内核代码、数据结构和设备驱动程序等。内核空间通常是操作系统中的一块保护内存区域,只有操作系统内核才能够访问这个区域。

内存映射段 是高效的 I/O 映射方式,用于装载一个共享的动态内存库。用户可使用系统接口
创建共享共享内存,做进程间通信。

关于内核空间及内存映射段,牵涉到操作系统,当前不做过多说明。

  • 19
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值