内存是计算机的重要部件之一。它是外存与CPU进行沟通的桥梁,计算机中所有程序的运行都在内存中进行。内存性能的强弱影响计算机整体发挥的水平。在软件与运行的过程,软件中需要使用的是数据代码都会加载到内存中运行。一般内存分为四个区域,称之为内存四区。这四个区域包括代码区、数据区、栈区和堆区。不同的区域存储的内容和分派的大小不一样。
代码区
代码区一般存放的数程序的代码程序,一般是软件在运行的时候加载到代码区的,当程序运行结束之后,这个区域就会被释放。
数据区
数据区也被称为是全局区或者静态区。这部分可以细分为data区和bss区。这个区域存储的是软件运行过程的一些存放初始化全局变量、存放初始化静态全局变量、存放初始化静态局部变量、未初始化的静态局部变量,默认值为0、未初始化的全局变量,默认值为0、未初始化的静态全局变量,默认值为0、字符串常量和defind定义的常量。
这个区域的数据和常量跟随软件的启动而创建,软件运行结束之后,内存区域才会释放。
栈区
栈区主要是在软件运行过程中创建的区域,一般存储的是一些局部变量、数组(只有C语言将数组存储在栈区)、结构体和枚举。这个区域的数据在程序运行的过程中创建,当创建的变量或者数组使用结束结束之后,在在函数结束之后释放。不同作用域的变量生命周期不同,因此释放的时间也不同。对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
栈区的大小不能由程序员开辟,而是根据系统的不同,栈区的空间大小也不相同。一般32位系统中window是1M~8M左右,Linux系统中是1M~16M。
栈区的创建没有什么特殊的函数,一般正常创建的变量都是存储在栈区的。
例如:
int a; char [0];
堆区
堆区也是存储一些大的结构体、数组等大文件,也可以存储一些音频文件、文本文件、视频文件、图像文件等。
堆空间的大小是由内存条的大小决定的,一般的堆区的大小数除去其他三区的空间大小,剩下的空间都是属于堆区的。对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;
堆区的空间的使用需要程序员自己手动开辟和释放,如果申请使用了堆区控件,不进行释放可能会造成程序内存的溢出导致程序崩溃。如果软在在运行过程,软件没有崩溃,堆区控件会在程序运行结束之后,自动释放。堆区空间不能重复释放,重复释放会释放空空间,导致软件崩溃。
堆区开辟空间的函数,常用的内存管理函数有以下三个:
1)分配内存空间函数malloc
调用形式:
(类型说明符*)malloc(size)
功能:在内存的动态存储区中分配一块长度为"size"字节的连续区域。函数的返回值为该区域的首地址。
“类型说明符”表示把该区域用于何种数据类型。
(类型说明符*)表示把返回值强制转换为该类型指针。
“size”是一个无符号数。
例如:
pc=(char *)malloc(100);
表示分配100个字节的内存空间,并强制转换为字符数组类型,函数的返回值为指向该字符数组的指针,把该指针赋予指针变量pc。
2)分配内存空间函数 calloc, calloc 也用于分配内存空间。
调用形式:
(类型说明符*)calloc(n,size)
功能:在内存动态存储区中分配n块长度为“size”字节的连续区域。函数的返回值为该区域的首地址。
(类型说明符*)用于强制类型转换。
calloc函数与malloc 函数的区别仅在于一次可以分配n块区域。
例如:
ps=(struet stu*)calloc(2,sizeof(struct stu));
其中的sizeof(struct stu)是求stu的结构长度。因此该语句的意思是:按stu的长度分配2块连续区域,强制转换为stu类型,并把其首地址赋予指针变量ps。
3)释放内存空间函数free
调用形式:
free(void*ptr);
功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,它指向被释放区域的首地址。被释放区应是由malloc或calloc函数所分配的区域。
例如:堆空间的创建和释放需要使用malloc函数和free函数。
char aa[] = (char*)malloc(创建空间的大小);
struct DIC *p = (struct DIC *)malloc(1024);//这个例子就是在堆空间开辟一个结构体为DIC的堆空间,堆空间的大小为1024。p为开辟的堆空间的首地址。
free(p);//此函数是释放开辟的堆空间。
-
内存操作函数
1)memset
void * memset(void *s,int c, size_t n)
函数功能:将 s 的内存区域的前 n 个字节以参数 c 填入
参数:s 需要操作的内存地址
c 填入的字符,c虽然参数为int,但是必须是unsigned char,范围为0-255
n 指定需要设置的大小,以字节为单位
返回值:s 的首地址
2)memcpy
void * memcpy (void *dest,const void *src,size_t n)
函数功能:拷贝 src 所指的内存内容的前 n 个字节到 dest 所指的内存地址上
参数:dest 目的内存首地址
src 源内存首地址,注意:dest和src中的内存地址不能重复
n 需要拷贝的字节数(以字节为单位‘)
返回值:dest的首地址
3)memmove
memmove函数的功能和用法跟memcpy一样,区别在以memmove函数中dest和src所指的内存地址可以重叠。不过执行效率比memcpy函数低
4)memcmp
int memcmp(const void *s1,const void *s2,size_t n)
函数功能:比较 s1 和 s2 所指向内存区域的前 n 个字节
参数:s1 内存首地址
s2 内存首地址
n 比较字节的大小
返回值: 相等 =0
大于 >0
小于 <0