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);
- 虽然av_freep()函数很简单,就几行代码,但实际上很容易让人晕头,以一个示例来讲会比较清楚明白,如上述两行代码所示,展示了av_freep()函数的一般用法,注意,我们需要释放的是buf指向的内存,而传入av_freep()的并非是指针buf,而是buf指针所在的地址,又是一个double point。哎,一到双重指针就犯晕。
- 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这个指针指向这个空间咯,务必理解这点。 - memcpy(arg, &(void *){ NULL }, sizeof(val)); 有了2做分析基础,那么可以知道就是往arg指向的地址赋值为NULL,arg指向的地址是什么呢?arg为&buf,其实就是让buf这个指针指向了NULL,即buf=NULL。这样就解决了悬空指针的问题
- 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 }
- 注意HAVE_ALIGNED_MALLOC存在的情况下,ffmpeg使用av_malloc分配内存时,使用_aligned_malloc()库函数,因此,此处对应的也是使用内存对齐的释放函数_aligned_free()
#elif HAVE_ALIGNED_MALLOC ptr = _aligned_malloc(size, ALIGN); #elif HAVE_MEMALIGN
- 否则使用常规的c运行库 free()函数进行内存释放。