内存分区

内存对于很多人来说都会有一中,感觉很抽象有种很虚拟的感觉,内存是实体,是由很多内存条构成,
我们知道有每8个晶体管称为一个存储单元(一个字节),内存也划分了很多分区,而存储在不同区域的变量有不同的特性,如存储在栈中的我们必须给初始化
在程序中我们应该看到的不是变量,而是内存,变量名只是一个标识符,我们通过它操作内存
每一个变量都是有一个地址,在内存中占据一段内存,而变量名是这段内存的(标识),我们通过对入 int a=10; 我们是对a对应的内存段写入10,编程的本质是读写内存,,而存储在不同区域的变量,生命周期不同,作用域不同,如存储在全局区的变量,不初始化值就为0,
编译器在给变量分配内存的时候一般存储在同一个分区的变量地址比较接近(堆是个例外)

1,栈区 :局部变量都是在栈上开辟的空间,在函数体内定义的变量(不包刮静态变量),在内存中地址较高,由于栈的特性,在函数结束
栈上的时在该函数里分配的内存全都被销毁。所以如果函数返回的时栈上的内存地址(因为该段内存已被销毁)是错误选择(虽然编译器不一定会报错)
2, 堆区 :在堆上开辟空间就是我们常称为动态内存分配 由malloc calloc 等函数在堆上开辟空间,需要我们用free函数
手动的释放申请到的空间,一般一个malloc 对应一个free ,若不释放程序结束时由OS回收,建议在程序结束前手动释放
3,全局区:我们定义的全局变量,和静态变量,全部存储在全局区,我们知道全局变量或静态变量不初始化默认值未0,而局部变量
不初始化的值是个随机值,是由于全局分为三部分,初始化全局区存放初始化的全局变量和静态变量,和未初始化全局区存放
未初始化的全局变量和静态变量,和字符串常量区。
4,代码区:代码区用于存放程序执行的二进制代码,和数字常量如1 ,2等我们无法得到它们的地址
在这里插入图片描述
#include<stdio.h>
#include<stdlib.h>
#define N “hello world”
#define M 2
int n=10;
int m;
int main(){
char q=(char)malloc(sizeof(char));
char a[]=“hello world”;
a[1]=‘T’;
char p= “hello world”;//使char类型指针变量 指向 常量区的"hello world"
//p[1]=‘T’;
printf(“a栈=%x\t字符串常量p=%x\t字符串常量N=%x\n”,a,p,&N);

	 printf("n data=%d\tm bss=%d",&n,&m);
	 int c=10;
	 printf("q堆=%x",q);
	 printf("\tc栈=%x\tM=%x\n",&c,M);//M的地址得不到 
	 printf("ll字符串常量=%p","taolaoda"); 
	 free(q);

}
在这里插入图片描述

涉及内存的地方一般都涉及指针,指针向用来指向内存中的一段空间,这是指针的定义,指针的使用很危险,没有丰富的经验,很难安全合法的使用指针,就像人类社会一样,我们有法律,什么事可以做,什么事不可以做,指针也一样
如指向一个没有被分配的空间的指针被操作,
#include<Stdio.h>
int main(){
int *b;
printf("%p\n",b);
b=10; //操作一个没有被分配的空间 并往里写数据是非法的,程序可以运行但是会崩溃
printf(“hello world”);
}
看着程序运行的结果,导论
b=10;这里直接崩溃,非法区域是由保护的(不是保护你的程序是保护系统),例如如果没有保护你改的时操作系统的数据那就麻烦大了,
在这里插入图片描述非法
#include<Stdio.h>
#include<stdlib.h>
int main(){
int *p=(int *)malloc(sizeof(int));
*p=100;
printf("*p=%d\tp=%p\n",*p,p);
free§;
printf("*p=%d\tp=%p",p,p);
}
还有这里指针指向的空间已经的释放,指针还是会指向它,并不会变,但是这段内存中的数据已经是垃圾数据了,试想你的程序得到一个垃圾数据用于运算,可能产生什么后果,因为这个指针之前指向的区域是合法的,虽然之后空间释放了,不会出现上一个程序那样的,操作非法内存程序直接崩溃,这也是我们需要注意,可能会是你的程序结果完全错误,这是我们所需要避免的
在这里插入图片描述
#include<Stdio.h>
int
fun(int a){
printf(“a=%p\t%d\n”,&a,a);
return &a;
}
int main(){
int a=10;
int *c=fun(a);
printf("%p",c);
printf("\t%d",*c);
}
返回局部变量(栈)的内存地址,这也是一样,指向一段已经释放的内存,也经常是我们犯的错误,这些错误都难以找出,都需要我们犯错,才能真正的理解,获得成长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值