【C语言】动态内存管理

更灵活的内存管理方式

在C语言中不存在其他高级语言的垃圾回收机制,在平常方式直接的声明变量,C语言不知道什么时候回收它,所以会一直占用内存空间.而更灵活的管理就是我们能在不使用该变量时就主动释放它。

申请的空间不在使用,一定要释放(free(),虽然不是一定释放,但这是一个好习惯

使用的库

需要引入 #include <stdlib.h>

  • void *malloc(size_t size); 申请动态内存空间
  • void free(void *ptr); 释放动态内存空间
  • void *calloc(size_t nmemb, size_t size); 申请并初始化内存空间为 0
  • void *realloc(void *ptr, size_t size); 重新分配内存空间

申请空间 & 释放空间

void *malloc(size_t size);

  • 申请成功:返回一个指向申请的内存空间的指针,返回值是 void 所以可以转化成其他类型
  • 申请失败:返回 NULL
  • 如果 size 参数设置为 0,返回值也可能是 NULL,但这并不意味着函数调用失败。

void free(void *ptr);

  • 只能释放由 malloccallocrealloc函数申请的空间,释放后该地址变为非法地址
    • 参数指向将要释放的内存空间的地址
    • 没有返回值
#include <stdio.h>
#include <stdlib.h>  // 引入

int main(){
    // 申明变量
    int *ptr,num = 520;

    // 申请内存空间
    ptr = (int *)malloc(sizeof(int));
    if (ptr == NULL){exit(1);} // 内存申请失败

    // 内存空间存入变量
    ptr = &num;

    // 输出值
    printf("prt -> %d",*ptr);

    // 释放内存空间
    free(ptr);

    return 0;
}

mark

内存泄漏

内存泄漏是程序一直占用内存,不释放,造成内存达到很高的使用量,严重造成计算机卡死,所以在不使用该空间时尽量释放掉。

有两种情况会导致:

  • 隐式内存泄漏(即用完内存块没有及时使用 free 函数释放)
  • 丢失内存块地址

申请并初始化 & 重新分配

申请并初始化

void *calloc(size_t nmemb, size_t size);

  • nmemb:指定分配的内存块个数
  • size:指定每个内存块的大小,以字节为单位。
#include <stdio.h>
#include <stdlib.h>

int main(){
    // 初始化变量
    int *ptr = NULL;

    // 申请并初始化变量
    ptr = (int *)calloc(10,sizeof(int));
    if(ptr == NULL){exit(1);}

    // 查看内容
    for (int i = 0; i < 10; ++i) {printf("%d ",ptr[i]);};
    printf("\n");

    return 0;
}

mark

重新分配内存空间

只能重新分配 malloc()函数 申请的空间

void *realloc(void *ptr, size_t size); 重新分配内存空间

  • 参数 *ptr
    • 指向由先前调用 malloc、calloc 或 realloc 函数返回的内存空间
    • 如果传入NULL,相当于调用 malloc(size) 函数
  • 参数 size : 指定新的内存块空间大小,以字节为单位
  • 该函数将移动内存空间的数据并返回新的指针
  • 如果新分配的内存空间比原来的大,则旧内存块的数据不会发生改变;如果新的内存空间大小小于旧的内存空间,可能会导致数据丢失慎用!
#include <stdio.h>
#include <stdlib.h>

int main(){
    // 初始化变量
    int *ptr = NULL;

    // 申请并初始化变量
    ptr = (int *)malloc(10 * sizeof(int));
    if(ptr == NULL){exit(1);}

    // 重新分配内存空间
    ptr = (int *)realloc(ptr,20 * sizeof(int));
    printf("%llu",sizeof(ptr));

    ptr[12] = 66666666; // 赋值

    // 查看内容
    for (int i = 0; i < 20; ++i) {
        printf("%d ",ptr[i]);
    }

    return 0;
}

mark

发表评论 / Comment

用心评论~