内存管理:
????????主要是指对“堆”内存的管理和使用
C语言的内存存储方式如下:
?
1. 栈区 栈区介绍: 栈区由编译器自动分配释放,由操作系统自动管理,无须手动管理。 栈区上的内容只在函数范围内存在,当函数运行结束,这些内容也会自动被销毁。 栈区按内存地址由高到低方向生长,其最大大小由编译时确定,速度快,但自由性差,最大空间不大。 栈区是先进后出原则,即先进去的被堵在屋里的最里面,后进去的在门口,释放的时候门口的先出去。 存放内容 临时创建的局部变量和const定义的局部变量存放在栈区。 函数调用和返回时,其入口参数和返回值存放在栈区。
2. 堆区 堆区介绍: 堆区由程序员分配内存和释放。 堆区按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,速度较慢,但自由性大,可用空间大。
栈向下拓展,堆向上拓展
开辟内存的时候,我们常用的是数组,但是数组在申明的时候必须指定数组的长度,但有时候我们并不知道这个数组需要的空间是多大,对于空间的需求只有在运行的时候才知道,所以我们需要用动态内存开辟空间。
申请内存:
1.malloc——动态内存申请
函数原型: void *malloc(size_t size);? malloc函数向系统申请分配size个字节的内存空间,并返回一个指向这块空间 的指针。 如果函数调用成功,返回一个指向申请的内存空间的指针,由于返回类型是 void指针(void *),所以它可以被转换成任何类型的数据;如果函数调用失 败,返回值是NULL。另外,如果size参数设置为0,返回值也可能是NULL,但 这并不意味着函数调用失败。
《C语言参考手册》上说”如果请求的长度为0,则标准C语言函数返回一个null指针或不能用于访问对象的非null指针。”
?
2.free——释放动态内存
函数原型: void free(void *ptr);? free函数释放ptr参数指向的内存空间,该内存空间必须是由malloc、calloc或realloc函数申请的动态内存;否则,该函数将导致未定义行为。如果ptr参数是NULL,则不执行任何操作。该函数不会修改参数的值,所以调用后它仍然指向原来的地方。
?因为已经把动态内存释放掉了,所以之后再输出ptr就不能得到正确的数,因为它变成了野指针
3.calloc—申请并初始化一系列内存空间
函数原型: void* calloc(size_t nmemb,size_t size);? ? nmemb是元素的个数 calloc函数在内存中动态地申请nmemb个长度为size的连续内存空间 (即申请的内存空间尺寸为nmemb * size),这些内存空间全部被初始化为0 calloc函数在申请完内存后,自动初始化该内存空间为零 但是malloc函数申请完内存空间后不会自动初始化
?memset函数是将数字以单个字节逐个拷贝的方式放到指定的内存中去的
int类型的变量一般占用4个字节,对每一个字节赋值0的话就变成了“00000000 00000000 000000000 00000000” (即10进制数中的0)
4.realloc——重新分配内存空间
函数原型: void* realloc(void* ptr,size_t size); realloc函数修改ptr指向的内存空间大小为size字节 如果新分配的内存空间比原来的大,则旧内存块的数据不会发生改变;如果新的内存空 间大小小于旧的内存空间,可能会导致数据丢失。 该函数将移动内存空间的数据并返回新的指针 如果ptr参数为NULL,那么调用该函数就相当于调用malloc(size) 如果size参数为0,并且ptr参数不为NULL,那么调用该函数就相当于调用free(ptr) 除非ptr参数为NULL,否则ptr的值必须由先前调用malloc、calloc或realloc函数返回?
内存泄漏:
内存单元被一直占据,造成系统内存的浪费,累积之后会导致程序运行速度减慢甚至系统崩溃等后果
1.使用完空间之后没有将其释放
2.内存块的地址丢失了
ptr指向malloc申请的内存空间的地址,之后又让ptr指向另外一个整数的地址,那么malloc的内存空间地址就丢失了
空间拓展:
对已申请的内存空间需要拓展
使用memcpy()函数
?void *memcpy(void *ptr2, const void *ptr1, size_t n)
从ptr1复制n个字节到ptr2
感谢观看!!!
对动态内存存储还不是很明白,若有不足,还请斧正。
|