FFMPEG4.1源码分析之 内存管理APIs av_freep() && av_free()

1. av_freep()


av_freep() 声明:

  • 所属库:libavutil(lavu),libavutil是ffmpeg的工具类库,本函数是其内存管理类库中的函数
  • 头文件:libavutil/mem.h
  • 声明:释放一个内存块,这个内存块由av_malloc()/av_realloc()家族函数来分配的,并且将指针置为NULL。注意看函数说明,对于av_free()函数的使用会导致悬空指针,而av_freep()函数不会导致悬空指针,关于悬空指针的论述见文章 野(wild)指针与悬空(dangling)指针
               1) 重点一:该函数可以解决悬空指针的问题!!!这个确实是很大的改进!!!,如何实现的见后文分析
               2) 重点二:传入的ptr解释为“Pointer to the pointer to the memory block which should be freed”,ptr应该是双重指针!!!
  • /**
     * Free a memory block which has been allocated with a function of av_malloc()
     * or av_realloc() family, and set the pointer pointing to it to `NULL`.
     *
     * @code{.c}
     * uint8_t *buf = av_malloc(16);   
     * av_free(buf);
     * // buf now contains a dangling pointer to freed memory, and accidental
     * // dereference of buf will result in a use-after-free, which may be a
     * // security risk.
     *
     * uint8_t *buf = av_malloc(16);
     * av_freep(&buf);
     * // buf is now NULL, and accidental dereference will only result in a
     * // NULL-pointer dereference.
     * @endcode
     *
     * @param ptr Pointer to the pointer to the memory block which should be freed
     * @note `*ptr = NULL` is safe and leads to no action.
     * @see av_free()
     */
    void av_freep(void *ptr);

av_freep() 源码:

  • 源文件:libavutil/mem.c
    void av_freep(void *arg)
    {
        void *val;
    
        memcpy(&val, arg, sizeof(val));
        memcpy(arg, &(void *){ NULL }, sizeof(val));
        av_free(val);
    }
    
     * uint8_t *buf = av_malloc(16);
     * av_freep(&buf);
  1. 虽然av_freep()函数很简单,就几行代码,但实际上很容易让人晕头,以一个示例来讲会比较清楚明白,如上述两行代码所示,展示了av_freep()函数的一般用法,注意,我们需要释放的是buf指向的内存,而传入av_freep()的并非是指针buf,而是buf指针所在的地址,又是一个double point。哎,一到双重指针就犯晕。
  2. memcpy(&val, arg, sizeof(val)); 该函数将arg指向的内存地址开始的数据,拷贝sizeof(val)个byte数据,到&val开头的地址处。我们一个个来分析都是啥:
            1)如示例所知,arg为&buf,那么arg指向的buf这个指针;
            2)由于val类型为void*,因此,sizeof(val)为地址长度,一般是4字节;   
            3)由1)2)可知其实就是拷贝buf的值,也即需要释放的空间(由av_malloc(16)分配的空间)的地址
            4)这个地址值拷贝到&val,也即让val这个指针指向这个空间咯,务必理解这点。
  3.  memcpy(arg, &(void *){ NULL }, sizeof(val)); 有了2做分析基础,那么可以知道就是往arg指向的地址赋值为NULL,arg指向的地址是什么呢?arg为&buf,其实就是让buf这个指针指向了NULL,即buf=NULL。这样就解决了悬空指针的问题
  4.  av_free(val)来释放av_malloc(16)分配的空间,见后续av_free()的分析。

2 av_free()


av_free() 声明:

  • 所属库:libavutil(lavu) ,libavutil是ffmpeg的工具类库,本函数是其内存管理类库中的函数
  • 头文件:libavutil/mem.h
  • 声明:释放一个使用av_malloc()/av_realloc()函数分配的内存块。
              1)ptr就于av_freep()的入参ptr不一样咯,“Pointer to the memory block which should be freed”,直接就是指向要释放空间的指针了;
              2)ptr可以为NUL
              3)推荐使用av_freep()而非av_free(),以避免留下悬空指针~~
    /**
     * Free a memory block which has been allocated with a function of av_malloc()
     * or av_realloc() family.
     *
     * @param ptr Pointer to the memory block which should be freed.
     *
     * @note `ptr = NULL` is explicitly allowed.
     * @note It is recommended that you use av_freep() instead, to prevent leaving
     *       behind dangling pointers.
     * @see av_freep()
     */
    void av_free(void *ptr);
    

av_free() 源码:

  • 源文件:libavutil/mem.c
    void av_free(void *ptr)
    {
    #if HAVE_ALIGNED_MALLOC
        _aligned_free(ptr);
    #else
        free(ptr);
    #endif
    }
  1.  注意HAVE_ALIGNED_MALLOC存在的情况下,ffmpeg使用av_malloc分配内存时,使用_aligned_malloc()库函数,因此,此处对应的也是使用内存对齐的释放函数_aligned_free()
    #elif HAVE_ALIGNED_MALLOC
        ptr = _aligned_malloc(size, ALIGN);
    #elif HAVE_MEMALIGN
  2. 否则使用常规的c运行库 free()函数进行内存释放。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值