当前位置: 首页 > news >正文

用boostrap做的网站关键词完整版免费听

用boostrap做的网站,关键词完整版免费听,网站的网站制作,做设计专业的能做网站吗一、av_malloc函数分析 (一)av_malloc函数的声明 av_malloc函数的声明放在在FFmpeg源码(本文演示用的FFmpeg源码版本为5.0.3,该ffmpeg在CentOS 7.5上通过10.2.1版本的gcc编译)的头文件libavutil/mem.h中:…

一、av_malloc函数分析

(一)av_malloc函数的声明

av_malloc函数的声明放在在FFmpeg源码(本文演示用的FFmpeg源码版本为5.0.3,该ffmpeg在CentOS 7.5上通过10.2.1版本的gcc编译)的头文件libavutil/mem.h中:

/*** Allocate a memory block with alignment suitable for all memory accesses* (including vectors if available on the CPU).** @param size Size in bytes for the memory block to be allocated* @return Pointer to the allocated block, or `NULL` if the block cannot*         be allocated* @see av_mallocz()*/
void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1);

根据注释,可以了解到该函数作用是分配一个适合所有内存访问的内存块(包括动态数组,如果CPU上可用)。形参size:要分配的内存块的字节大小。返回值:指向分配块的指针;如果无法申请内存,则返回NULL。

宏定义av_malloc_attrib也被定义在libavutil/mem.h中:

/*** @def av_malloc_attrib* Function attribute denoting a malloc-like function.** @see <a href="https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-g_t_0040code_007bmalloc_007d-function-attribute-3251">Function attribute `malloc` in GCC's documentation</a>*/#if AV_GCC_VERSION_AT_LEAST(3,1)#define av_malloc_attrib __attribute__((__malloc__))
#else#define av_malloc_attrib
#endif

这里用attribute指定__malloc__属性,表示这样标记的函数(av_malloc函数)返回的块不得包含任何指向其他对象的指针。这样做的目的是帮助编译器估计哪些指针可能指向同一个对象:该属性告诉GCC,它不必担心函数返回的对象可能包含指向它正在跟踪的其他对象的指针。具体可以参考:GCC: __attribute__((malloc))

宏定义av_malloc_attrib也被定义在libavutil/mem.h中:

/*** @def av_alloc_size(...)* Function attribute used on a function that allocates memory, whose size is* given by the specified parameter(s).** @code{.c}* void *av_malloc(size_t size) av_alloc_size(1);* void *av_calloc(size_t nmemb, size_t size) av_alloc_size(1, 2);* @endcode** @param ... One or two parameter indexes, separated by a comma** @see <a href="https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-g_t_0040code_007balloc_005fsize_007d-function-attribute-3220">Function attribute `alloc_size` in GCC's documentation</a>*/#if AV_GCC_VERSION_AT_LEAST(4,3)#define av_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__)))
#else#define av_alloc_size(...)
#endif

这里用attribute指定alloc_size属性,用于告诉编译器函数返回值指向的内存,其大小是由alloc_size中的参数指定,主要用于提高__builtin_object_size的正确性。具体参考:GCC __atrribute__

然后宏定义用到了变参__VA_ARGS__,可以参考:C 语言 define 变参__VA_ARGS__使用

所以函数声明void *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1) 等价于:

void *av_malloc(size_t size) __attribute__((__malloc__)) __attribute__((alloc_size(1)))

简单来讲,__attribute__只是让代码优化得更好而已,我们可以忽略。

(二)av_malloc函数的实现原理

av_malloc函数定义在libavutil/mem.c中:

#define HAVE_POSIX_MEMALIGN 1
#define HAVE_ALIGNED_MALLOC 0
#define HAVE_MEMALIGN 1
#define HAVE_AVX512 0
#define HAVE_AVX 0
#define CONFIG_MEMORY_POISONING 0
#define ALIGN (HAVE_AVX512 ? 64 : (HAVE_AVX ? 32 : 16))static atomic_size_t max_alloc_size = ATOMIC_VAR_INIT(INT_MAX);void *av_malloc(size_t size)
{void *ptr = NULL;if (size > atomic_load_explicit(&max_alloc_size, memory_order_relaxed))return NULL;#if HAVE_POSIX_MEMALIGNif (size) //OS X on SDK 10.6 has a broken posix_memalign implementationif (posix_memalign(&ptr, ALIGN, size))ptr = NULL;
#elif HAVE_ALIGNED_MALLOCptr = _aligned_malloc(size, ALIGN);
#elif HAVE_MEMALIGN
#ifndef __DJGPP__ptr = memalign(ALIGN, size);
#elseptr = memalign(size, ALIGN);
#endif/* Why 64?* Indeed, we should align it:*   on  4 for 386*   on 16 for 486*   on 32 for 586, PPro - K6-III*   on 64 for K7 (maybe for P3 too).* Because L1 and L2 caches are aligned on those values.* But I don't want to code such logic here!*//* Why 32?* For AVX ASM. SSE / NEON needs only 16.* Why not larger? Because I did not see a difference in benchmarks ...*//* benchmarks with P3* memalign(64) + 1          3071, 3051, 3032* memalign(64) + 2          3051, 3032, 3041* memalign(64) + 4          2911, 2896, 2915* memalign(64) + 8          2545, 2554, 2550* memalign(64) + 16         2543, 2572, 2563* memalign(64) + 32         2546, 2545, 2571* memalign(64) + 64         2570, 2533, 2558** BTW, malloc seems to do 8-byte alignment by default here.*/
#elseptr = malloc(size);
#endifif(!ptr && !size) {size = 1;ptr= av_malloc(1);}
#if CONFIG_MEMORY_POISONINGif (ptr)memset(ptr, FF_MEMORY_POISON, size);
#endifreturn ptr;
}

去掉一大堆其它东西,av_malloc函数的核心实现就是:

void *av_malloc(size_t size)
{//...void *ptr = NULL;if (posix_memalign(&ptr, ALIGN, size)){ptr = NULL;}//...return ptr;}	

可以看到其本质就是调用了posix_memalign函数,该函数是Linux下内存对齐的函数,其作用是分配size大小的字节,并将分配的内存地址存放在ptr中。分配的内存的地址将是ALIGN的倍数,且必须是2的幂次方和sizeof(void*)的倍数。如果size为0,则函数返回NULL或一个唯一的指针值,以便可以成功传递给free函数。如果分配成功返回0该函数跟malloc函数相近。mallocposix_memalign函数跟mallocmalloc函数的区别是: malloc函数总是返回8字节对齐的内存地址,在64bits上是16字节对齐;而对于更大的边界,例如页面,需要动态的对齐的时候就可以选择posix_memalign函数。具体可以参考:posix_memalign(3) — Linux manual page

总结:av_malloc函数作用是分配一个适合所有内存访问的内存块,形参size为 要分配的内存块的字节大小。其底层实现就是调用了posix_memalign函数。

二、av_mallocz函数分析

(一)av_mallocz函数的声明

av_mallocz函数的声明放在在FFmpeg源码的头文件libavutil/mem.h中:

/*** Allocate a memory block with alignment suitable for all memory accesses* (including vectors if available on the CPU) and zero all the bytes of the* block.** @param size Size in bytes for the memory block to be allocated* @return Pointer to the allocated block, or `NULL` if it cannot be allocated* @see av_malloc()*/
void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1);

根据注释,可以了解到该函数作用是分配一个适合所有内存访问的内存块
(包括CPU上可用的动态数组)并将块的所有字节归零。形参size:要分配的内存块的字节大小。
返回值指向已分配块的指针,如果不能分配,则为NULL。

(二)av_mallocz函数的实现原理

av_mallocz函数定义在libavutil/mem.c中:

void *av_mallocz(size_t size)
{void *ptr = av_malloc(size);if (ptr)memset(ptr, 0, size);return ptr;
}

可以看到其核心就是调用了av_malloc函数分配内存块,随后调用memset函数将该内存块的所有字节清零。因为av_mallocz函数会将内存块清零(相当于对内存块进行一个初始化操作)。所以在FFmpeg源码中一般使用av_mallocz,而不会直接使用av_malloc函数。

三、av_free函数分析

(一)av_free函数的声明

av_free函数的声明放在在FFmpeg源码的头文件libavutil/mem.h中:

/*** 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_malloc()/av_mallocz()函数分配的内存块。形参ptr:指向应该释放的内存块的指针。
 

(二)av_free函数的实现原理

av_free函数定义在libavutil/mem.c中:

void av_free(void *ptr)
{
#if HAVE_ALIGNED_MALLOC_aligned_free(ptr);
#elsefree(ptr);
#endif
}

可以看到其核心就是调用free函数释放空间。

四、av_freep函数分析

(一)av_freep函数的声明

av_freep函数的声明放在在FFmpeg源码的头文件libavutil/mem.h中:

/*** 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_malloc()/av_mallocz()函数分配的内存块,并设置指向它的指针为NULL 。

(二)av_freep函数的实现原理

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);
}

可以看到其核心就是调用了av_free函数释放空间。然后av_freep函数可以避免仅使用av_free函数释放空间后出现的悬挂指针,避免安全风险。所以av_freep函数比仅使用av_free函数更安全。

五、编写测试例子,来理解av_mallocz函数和av_freep函数的使用

通过上述的讲解,相信大家已经了解了FFmpeg源码中这几个内存相关的函数,也理解了FFmpeg 源码中C语言的设计艺术。就拿FFmpeg的内存相关的函数来讲,其设计艺术在于:av_mallocz函数申请、分配内存后,还会对该内存块进行初始化清零的操作;av_freep函数在释放内存块空间后会把指针指向NULL。我们可以把av_mallocz函数和av_freep函数从FFmpeg源码中抽取出来,移植到我们自己的C语言代码中使用。这样在不依赖FFmpeg库文件的情况下,我们也能使用FFmpeg里面的函数。这就是最简单的对FFmpeg裁剪。

编写测试例子main.c,在CentOS 7.5上通过10.2.1版本的gcc可以成功编译 :

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <stdatomic.h>
#include <limits.h>#define HAVE_POSIX_MEMALIGN 1
#define HAVE_ALIGNED_MALLOC 0
#define HAVE_MEMALIGN 1
#define HAVE_AVX512 0
#define HAVE_AVX 0
#define CONFIG_MEMORY_POISONING 0
#define ALIGN (HAVE_AVX512 ? 64 : (HAVE_AVX ? 32 : 16))static atomic_size_t max_alloc_size = ATOMIC_VAR_INIT(INT_MAX);#ifdef __GNUC__
#    define AV_GCC_VERSION_AT_LEAST(x,y) (__GNUC__ > (x) || __GNUC__ == (x) && __GNUC_MINOR__ >= (y))
#    define AV_GCC_VERSION_AT_MOST(x,y)  (__GNUC__ < (x) || __GNUC__ == (x) && __GNUC_MINOR__ <= (y))
#else
#    define AV_GCC_VERSION_AT_LEAST(x,y) 0
#    define AV_GCC_VERSION_AT_MOST(x,y)  0
#endif#if AV_GCC_VERSION_AT_LEAST(3,1)#define av_malloc_attrib __attribute__((__malloc__))
#else#define av_malloc_attrib
#endif#if AV_GCC_VERSION_AT_LEAST(4,3)#define av_alloc_size(...) __attribute__((alloc_size(__VA_ARGS__)))
#else#define av_alloc_size(...)
#endifvoid *av_malloc(size_t size) av_malloc_attrib av_alloc_size(1);
void *av_mallocz(size_t size) av_malloc_attrib av_alloc_size(1);
void av_free(void *ptr);
void av_freep(void *ptr);void *av_malloc(size_t size)
{void *ptr = NULL;if (size > atomic_load_explicit(&max_alloc_size, memory_order_relaxed))return NULL;#if HAVE_POSIX_MEMALIGNif (size) //OS X on SDK 10.6 has a broken posix_memalign implementationif (posix_memalign(&ptr, ALIGN, size))ptr = NULL;
#elif HAVE_ALIGNED_MALLOCptr = _aligned_malloc(size, ALIGN);
#elif HAVE_MEMALIGN
#ifndef __DJGPP__ptr = memalign(ALIGN, size);
#elseptr = memalign(size, ALIGN);
#endif/* Why 64?* Indeed, we should align it:*   on  4 for 386*   on 16 for 486*   on 32 for 586, PPro - K6-III*   on 64 for K7 (maybe for P3 too).* Because L1 and L2 caches are aligned on those values.* But I don't want to code such logic here!*//* Why 32?* For AVX ASM. SSE / NEON needs only 16.* Why not larger? Because I did not see a difference in benchmarks ...*//* benchmarks with P3* memalign(64) + 1          3071, 3051, 3032* memalign(64) + 2          3051, 3032, 3041* memalign(64) + 4          2911, 2896, 2915* memalign(64) + 8          2545, 2554, 2550* memalign(64) + 16         2543, 2572, 2563* memalign(64) + 32         2546, 2545, 2571* memalign(64) + 64         2570, 2533, 2558** BTW, malloc seems to do 8-byte alignment by default here.*/
#elseptr = malloc(size);
#endifif(!ptr && !size) {size = 1;ptr= av_malloc(1);}
#if CONFIG_MEMORY_POISONINGif (ptr)memset(ptr, FF_MEMORY_POISON, size);
#endifreturn ptr;
}void *av_mallocz(size_t size)
{void *ptr = av_malloc(size);if (ptr)memset(ptr, 0, size);return ptr;
}void av_free(void *ptr)
{
#if HAVE_ALIGNED_MALLOC_aligned_free(ptr);
#elsefree(ptr);
#endif
}void av_freep(void *arg)
{void *val;memcpy(&val, arg, sizeof(val));memcpy(arg, &(void *){ NULL }, sizeof(val));av_free(val);
}int main()
{uint8_t *pBuf = av_mallocz(128);if(pBuf){strcpy(pBuf, "hello world");printf("%s\n", pBuf);av_freep(&pBuf);if(!pBuf){printf("pBuf is free\n");}}return 0;
}

使用gcc编译,运行,输出如下:

六、参考文章

《FFmpeg5.0源码阅读——内存分配和释放》


文章转载自:
http://refrigerative.wwxg.cn
http://sabulous.wwxg.cn
http://laocoon.wwxg.cn
http://folivore.wwxg.cn
http://caproate.wwxg.cn
http://despondent.wwxg.cn
http://glimmer.wwxg.cn
http://profane.wwxg.cn
http://eventuate.wwxg.cn
http://slater.wwxg.cn
http://electrojet.wwxg.cn
http://xinca.wwxg.cn
http://misaim.wwxg.cn
http://valvate.wwxg.cn
http://excimer.wwxg.cn
http://program.wwxg.cn
http://deliver.wwxg.cn
http://reformative.wwxg.cn
http://cholestyramine.wwxg.cn
http://bah.wwxg.cn
http://cook.wwxg.cn
http://newshawk.wwxg.cn
http://osteomyelitis.wwxg.cn
http://armhole.wwxg.cn
http://xography.wwxg.cn
http://northumberland.wwxg.cn
http://scalenus.wwxg.cn
http://methodist.wwxg.cn
http://clouted.wwxg.cn
http://penicillamine.wwxg.cn
http://risc.wwxg.cn
http://at.wwxg.cn
http://disemployment.wwxg.cn
http://showily.wwxg.cn
http://barat.wwxg.cn
http://quaternion.wwxg.cn
http://orchidaceous.wwxg.cn
http://moroccan.wwxg.cn
http://noddy.wwxg.cn
http://intertie.wwxg.cn
http://tibial.wwxg.cn
http://lcvp.wwxg.cn
http://buddie.wwxg.cn
http://fleurette.wwxg.cn
http://vocalist.wwxg.cn
http://alpenhorn.wwxg.cn
http://ruminative.wwxg.cn
http://archery.wwxg.cn
http://papistry.wwxg.cn
http://burnouse.wwxg.cn
http://solidary.wwxg.cn
http://oujda.wwxg.cn
http://hexobiose.wwxg.cn
http://clout.wwxg.cn
http://surfperch.wwxg.cn
http://unroost.wwxg.cn
http://decuplet.wwxg.cn
http://peristalsis.wwxg.cn
http://forerunner.wwxg.cn
http://epineurial.wwxg.cn
http://semiangle.wwxg.cn
http://tenent.wwxg.cn
http://jps.wwxg.cn
http://byland.wwxg.cn
http://valuable.wwxg.cn
http://unguard.wwxg.cn
http://lateritization.wwxg.cn
http://bozzetto.wwxg.cn
http://ostentatious.wwxg.cn
http://saucerize.wwxg.cn
http://repristination.wwxg.cn
http://unconvince.wwxg.cn
http://discriminate.wwxg.cn
http://disaccharidase.wwxg.cn
http://synthetical.wwxg.cn
http://accessories.wwxg.cn
http://thingumbob.wwxg.cn
http://punny.wwxg.cn
http://feria.wwxg.cn
http://adactylous.wwxg.cn
http://nidification.wwxg.cn
http://smoothen.wwxg.cn
http://anourous.wwxg.cn
http://aperitive.wwxg.cn
http://nymphenburg.wwxg.cn
http://tenebrious.wwxg.cn
http://blustering.wwxg.cn
http://newmown.wwxg.cn
http://bbb.wwxg.cn
http://paillard.wwxg.cn
http://zonule.wwxg.cn
http://defray.wwxg.cn
http://decarbonize.wwxg.cn
http://luciferase.wwxg.cn
http://discard.wwxg.cn
http://gild.wwxg.cn
http://achroglobin.wwxg.cn
http://shmaltz.wwxg.cn
http://rentier.wwxg.cn
http://urbanise.wwxg.cn
http://www.hrbkazy.com/news/78083.html

相关文章:

  • 服务外包下的网站开发广州线上教学
  • 超好看WordPress重庆seo公司怎么样
  • 视频直播app开发成都关键词优化排名
  • 长春做网站优化价格网络营销的优势有哪些
  • 江苏网站建设包括哪些搜索引擎营销的模式有哪些
  • 建设项目管理公司网站如何推广一个平台
  • 网站测试的必要性360建站和凡科哪个好
  • 网站建设前台后台网络营销毕业论文8000字
  • 合肥网络推广策划方案seo软文是什么意思
  • b2b网站建设费用东营网站建设
  • 艾瑞网站建设宁波seo外包推广软件
  • 西安网站建设专业影响seo排名的因素有哪些
  • 请人做软件开发的网站海南seo排名优化公司
  • 做服装网站需要什么条件seo专员工作内容
  • 先做个在线电影网站该怎么做怎么把自己的网站发布到网上
  • 男生学平面设计好就业吗天津关键词优化网排名
  • 做网站需不需要云数据库杭州seo网站排名
  • 贵港公司做网站重庆广告公司
  • 用php做的博客网站有哪些自媒体发布软件app
  • 德州网站建设教程西安seo优化系统
  • 个人可以做导航网站吗seo短期课程
  • 网站里的活动专题栏怎么做站长查询域名
  • 网站app充值记账凭证怎么做微信营销是什么
  • 石家庄 网站开发百度网站安全检测
  • 怎么做网站用dreamwer免费做网站的网站
  • 不会做网站能做网络销售吗长沙seo优化推荐
  • 同一网站相同form id2345网址导航官网下载安装
  • 郑州市网络设计网站关键词百度自然排名优化
  • 网络网站建设推广域名解析在线查询
  • 零成本搭建自己的网站东莞seo建站哪家好