项少龙 为什么不和善柔:x264_malloc及free

来源:百度文库 编辑:九乡新闻网 时间:2024/04/30 00:47:26

  1. void *x264_malloc( int i_size )
  2. {
  3. #ifdef SYS_MACOSX
  4.     /* Mac OS X always returns 16 bytes aligned memory */
  5.     return malloc( i_size );
  6. #elif defined( HAVE_MALLOC_H )
  7.     return memalign( 16, i_size );
  8. #else
  9.     uint8_t * buf;
  10.     uint8_t * align_buf;
  11.     buf = (uint8_t *) malloc( i_size + 15 + sizeof( void ** ) +
  12.               sizeof( int ) );
  13.     align_buf = buf + 15 + sizeof( void ** ) + sizeof( int );
  14.     align_buf -= (long) align_buf & 15;
  15.     *( (void **) ( align_buf - sizeof( void ** ) ) ) = buf;
  16.     *( (int *) ( align_buf - sizeof( void ** ) - sizeof( int ) ) ) = i_size;
  17.     return align_buf;
  18. #endif
  19. }
做移植时刚好看到这一段,开始也搞不明白。后来查了一,这其中有两个关键点:
1是二级指针的使用,二级指针可以看成是一个一维的指针数组。
2是内存管理思想。
下面具体分析一下:
这段代码主要是为了实现:返回一个16字节对齐的 i_size 大小的内存;同时再分配该内存时添加了一些额外信息在所分配的内存的头部。
  1. buf = (uint8_t *) malloc( i_size + 15 + sizeof( void ** ) +sizeof( int ) );
上面的代码中
15 + sizeof( void ** ) +sizeof( int )
是为了字节对齐以及放置所分配的内存块的额外添加的信息的。
  1. align_buf -= (long) align_buf & 15;
这里实现字节对齐
  1. *( (void **) ( align_buf - sizeof( void ** ) ) ) = buf;
复制代码这里 先获取 指针align_buf 前面一个二级指针的大小位置的指针,然后把该指针转换为二级指针(这里就是要使用二级指针可以等同为一维的指针数组的用法),再在转换后的二级指针前面加一个 * 运算符其实就是取该一维指针数组的第一个元素,该元素被赋值为 buf,也就是真正分配内存块的首指针。
  1. *( (int *) ( align_buf - sizeof( void ** ) - sizeof( int ) ) ) = i_size;
复制代码这里则是,获取指针align_buf前面 sizeof( void ** ) + sizeof( int ) 位置的指针,并转换为int型,然后取该指针的值并赋值为 i_size。也就是保存用户需求的内存块的大小,这个其实就是内存管理的思想的一点小体现。

下面再说一下,内存的释放:
  1. void H264_free( void *p )
  2. {
  3.     if( p )
  4.     {
  5. #if defined( HAVE_MALLOC_H ) || defined( SYS_MACOSX )
  6.         free( p );
  7. #else
  8.         free( *( ( ( void **) p ) - 1 ) );
  9. #endif
  10.     }
  11. }
按照上面的分析,指针p其实就是指针align_buf。经过上面的分析应该很容易就知道
*( ( ( void **) p ) - 1 )
这里得到的其实就是上面的 buf 指针。可见释放是不会造成内存泄露的。