Day14

内存管理

程序是静态的,进程是动态的

进程空间图示

Day14_第1张图片

栈内存

一般局部变量,函数会放在保存在栈中

特点: 
栈内存分配是从地址大的开始分配
栈内存存储的数据会自动释放
栈的内存大小有限,所以特别注意在使用递归时,栈溢出的问题

堆内存

基本概念
堆内存可以存放任意类型的数据,但是需要自己申请和释放
堆大小,想象中是无限大的,但是实际使用,受限于实际内存大小和内存是否连续
malloc函数
#include 
#include 
#include 
int main()
{
    /*
     * malloc作用:
     *   在堆内存中申请一块我们指定长度的空间
     * 格式:
     *   接收一个参数,用于指定需要申请空间的长度
     *   会返回一个 void * , 这个是万能指针,可以转化为任意类型的指针,会将
     *   申请好的内存地址放到void *中返回给我们
     * void * malloc(size_t _Size);
     *
     * 注意点:
     *   1.使用malloc函数的时候必须导入头文件 #include 
     *   2.通过malloc函数申请的空间默认存储的是垃圾数据,系统不会帮我们初始化
     *   所以malloc一般都会和memset函数结合使用
     *   3.free()函数可以手动释放申请的存储空间,传入的参数是要释放地址
     */
     /*
       (int*)是强制类型转换,malloc函数返回的是void*,而我们开辟的是4个字节,正好是int类型,所以最好将void*转换为int*,因为只有指针类型是int类型将来操作这块内存的时候,才知道操作多少个字节

     */
//    int *num = (int *)malloc(sizeof(int)); //在堆中开辟4个字节的存储空间
//    *num = 777;
//    printf("%i\n", *num);

    int *p = (int *)malloc(3 * sizeof(int)); //开辟12字节的存储空间
    p[0] = 1;
    p[1] = 3;
    p[2] = 5;

    memset(p, 0, 3 * sizeof(int)); //初始化p对应的内存空间为0
    for(int i = 0; i< 3; i++){
        printf("p[%i] = %i\n",i, p[i] );
    }
    // free函数只传入了存储地址,系统是如何知道应该释放多少个字节的存储空间的
    // 在利用malloc分配地址的时候,系统就偷偷保存了该指针对应的内存大小
    free(p); //释放存储空间
    return 0;
}
memset函数
memset函数作用:
  专门用于初始化一块内存空间,使用必须导入头文件 #include 
  可以传入三个参数
  第一个参数: 传入需要初始化内存地址
  第二个参数: 传入需要初始化的值
  第三个参数: 传入需要初始化长度多少个字节
memset(p, 0, 3 * sizeof(int)); //初始化p对应的内存空间为0
calloc函数

注意: 使用时也需要引用#include 头文件

#include 
#include 

int main()
{
    /*
     * calloc函数: 就是对malloc函数的封装,一般用于开辟数组的存储空间
     */
    // 告诉操作系统,需要开辟3块存储空间,每块占4个字节
    int *p = (int *)calloc(3,sizeof(int));
    p[0] = 1;
    p[1] = 2;
    p[2] = 3;

    printf("%i\n", p[0]);
    printf("%i\n", p[1]);
    printf("%i\n", p[2]);
    free(p);
    return 0;
}
realloc函数
#include 
#include 
int main()
{
    /*
     * realloc : 用于给内存扩容和缩容
     * 例如: 我们利用malloc分配4个字节的空间, 但是觉得不够用想增加,这时候使用
     * relloc函数,或者想减少分配的存储空间
     * 传递两个参数: 第一个参数是要扩容地址,第二个参数是扩容后内存的大小
     * 
     * 注意点: 
     *   利用malloc函数分配存储空间,必须是连续的,也就是在堆内存中分配内存空间
     * 必须是连续的,如果利用realloc函数进行扩容时候,后面没有连续的内存,那么系统
     * 会分配一块新内存
     */
    
    int *p1 = (int *)malloc(sizeof(int));
    // 给存储空间扩容
    int *p2 = (int *)realloc(p1, sizeof(int) *2);
    return 0;
}

你可能感兴趣的:(Day14)