内存管理的库函数介绍

内存管理函数(<string.h>)

  • 内存初始化/赋值(memset)

    • memset

      • 函数原型:void *memset( void *dest, int val, size_t count );
      • 功能:把dest指针后的count字节的空间,设置为值val

      注:memset是以Byte为单位的

  • 内存复制/拷贝(memcpy、memmove)

    • memcpy

      • 函数原型:void *memcpy( void *dest, const void *src, size_t count );
      • 功能:把src后的count字节的内容,从dest地址开始拷贝一份
      • 注意事项:
        • 若有重复的区间,则需要考虑从前拷贝/从后拷贝来避免(不推荐有重复区间使用memcpy)
        • 若要使用安全的函数,则考虑memmove
    • memmove

      • 函数原型:errno_t memmove_s(void *dest, rsize_t destsz, const void *src, rsize_t count);(c11起)

      • 功能:从 src 所指向的对象复制 count 个字节到 dest 所指向的对象。两个对象都被转译成 unsigned char 的数组。对象可以重叠:如同复制字符到临时数组,再从该数组到 dest 一般进行复制

        返回 dest 的副本(临时内存地址),当然更有意义的是 dest 本身

      • 注意事项:

        • 若 dest 所指向的字符数组大小 < count <= destsz 则行为未定义
  • 内存比较(memcmp)

    • memcmp
      • 函数原型:int memcmp( const void* lhs, const void* rhs, size_t count );
      • 功能:比较两个地址后count字节的内容,若相同则返回0

动态内存管理函数(stdlib.h)

数据的初始化有以下几种情况:

  • 数据在栈空间开辟

    特点:创建时,未初始化,且为随机值

    应用场景:局部变量、函数创建时开辟堆栈帧

  • 数据在堆空间开辟

    特点:创建时,未初始化,且为随机值

    应用场景:动态内存管理

  • 数据在静态区开辟

    特点:创建时,数据就已初始化为0

    应用场景:全局变量、函数地址、static修饰的局部变量

  • 动态内存的开辟/释放

    • malloc

      • 函数原型:void *malloc( size_t size );

      • 功能:在堆区开辟 size 字节大小的空间,并返回地址

      注:

      • malloc(0) 的行为是未定义的

      • 若开辟失败,malloc则会返回空指针,失败后可以使用 strerror 函数(参阅字符串库函数)打印错误信息

      • 返回值需要使用强制类型转化来使用

      • 若要初始化为0,建议用下面这种语法

        #include <stdlib.h>
        #include <string.h>
        
        int main() {
            void* ptr = malloc(3);
            memset(ptr, 0, 3);
            free(ptr);
            return 0;
        }
    • calloc

      • 函数原型:void* calloc( size_t num, size_t size );
      • 功能:在堆区开辟 num 个对象,每个对象 size 字节大小,并返回地址
      注:
      • 因为对齐需求的缘故,分配字节数不必等于 num*size
      • 与 malloc 不同,calloc会初始化内存为0!
      • 使用calloc可以很方便开辟一个数组,如 int* arr = (int*)calloc(10, sizeof(int));
    • free

      • 函数原型:void free( void *ptr );
      • 功能:把 ptr 指针进行解分配
      注:
      • 在使用free后,记得把不用的指针置为NULL(别死皮赖脸,记住人家的地址)
      • 使用时,和 开辟函数 组合使用,做到 “谁开辟谁释放”,写开辟时就写好释放
    • realloc

      • 函数原型:void *realloc( void *ptr, size_t new_size );
      • 功能:调整动态开辟的内存空间 ptr 的大小为 new_size
      注:
      • 如果原空间后面的内存空间足够追加,则realloc会在后面追加空间
      • 如果原空间后面的内存空间不足以追加,则会开辟一块新空间,把旧数据拷贝到新空间上面,并释放旧的空间
      • 若空间不够用,开辟失败则会返回NULL
      • 若传递的指针为空指针,则与malloc功能相同
      • 因为有可能改变地址,所以重新开辟后需要判空,再重新赋给记录地址的指针变量!
« 字符串处理的库函数介绍 ← 返回列表 自定义数据类型 »