动态内存分配
本讲内容
存储区划分
堆内存分配函数
其他内存分配函数
内存操作函数
1.内存区划
栈区 |
int a =3 |
堆区 |
malloc(255) |
静态存储区 |
static float h =1.36f |
常量区 |
“lanou” |
代码区 |
int getCount(){...} |
自定义函数位于栈顶
main函数位于栈底
main函数既是程序的入口,也是程序的出口。
stack(栈) FILO(先进后出)(相当于水杯单向)
queue(队列) FIFO(先进先出)(相当于火车站买票 双向出口)
栈内存分配原则:
由系统自动根据数据类型所占的字节数分配相应的存储空间,使用完成后,又由系统自动回收。
堆区
malloc 函数分配的内存。
手动分配,手动释放。
//string 数组是由系统自动字栈内存中分配的,在函数调用结束时由系统自动回收,所以不允许将栈内存中开辟的存储区域的首地址作为函数的返回值返回。编译器首先会报警告,其次其他函数即使接收到返回的地址也已经访问不到相应的内容。
在将函数内部定义的变量直接作为返回值,主调函数中定义的变量会拷贝返回值的内容,在函数调用结束时,函数内部定义的变量存储空间会被系统回收,而在主调函数中接受函数返回值的变量可以正常使用。
静态存储区
static int a =5;
static char string[255];
只初始化一次
初始化后内存值为0
只有程序退出才释放(永远存在)。
将变量定义的类型前加static则变量存储在静态存储区。
常量区
‘a’ 字符常量
5 整型常量
“iPhone” 字符串常量
常量占用内存,只读状态,绝不可修改!
char *string =“iphone”;
string [0]=‘a’;运行崩溃!
当指针变量来接收一个常量字符串的地址时,通过指针访问的数据是只读的,不能修改,一修改就会出现crash。
代码区
if(a>b){
printf(“%d”,a);
}
所有的语句编译后会生成CPU指令存储在代码区。
2.动态堆内存分配
void *malloc(unsigned int size);
返回的是内存的首地址。
内存释放
void free(void *)
free 函数的作用是释放内存,内存释放是标记删除。
3.其他分配函数
calloc
void *calloc(unsigned n,unsigned size)
分配n个size大小的空间,并且把该内存上所有的字节清零.
void *realloc(void *p,unsigned newSize);
按给定的地址以及给定的大小重新分配。
realloc做为重新分配函数,如果原有的堆内存后续的内存空间足够大,realloc函数就会对原有空间追加newsize-原有字节数,如果不够大,则会寻找一块新的newsize大小的内存空间,并且将原堆内存做free操作
4. 内存操作函数
内存拷贝
void *memcpy(void *dest,const void *source,size_t n)
从sourse指向的内存开始拷贝到dest,拷贝n个字节。
初始化内存
void *memset(void *s,int c, size_t n)
从
内存比较
int memcmp(const void *buf1.const void *buf2,unsign int count)
比较buf1和buf2指向的内存是否相同,比较count个字节