代码之家  ›  专栏  ›  技术社区  ›  sshashank124

alsa中alloca代替局部变量

  •  0
  • sshashank124  · 技术社区  · 6 年前

    我使用了一个示例C ALSA程序作为参考,并按照以下代码段运行:

    ...
    snd_ctl_event_t *event;
    snd_ctl_event_alloca(&event);
    ...
    

    基于ALSA源代码, snd_ctl_event_alloca __snd_alloca 它是一个宏,最后扩展到 snd_ctl_event_alloca(&event); (简单明了):

    event = (snd_ctl_event_t *) alloca(snd_ctl_event_sizeof());
    memset(event, 0, snd_ctl_event_sizeof());
    

    哪里 snd_ctl_event_sizeof() 在整个库中只实现一次,如下所示:

    size_t snd_ctl_event_sizeof()
    {
        return sizeof(snd_ctl_event_t);
    }
    

    所以我的问题是,这整个过程不等于简单地做:

    snd_ctl_event_t event = {0};
    

    以下是宏供参考:

    #define snd_ctl_event_alloca(ptr) __snd_alloca(ptr, snd_ctl_event)
    #define __snd_alloca(ptr,type) do { *ptr = (type##_t *) alloca(type##_sizeof()); memset(*ptr, 0, type##_sizeof()); } while (0)
    

    澄清:

    • 上面的第一个代码块位于函数体的开头,而不是嵌套块

    事实证明(据我所知),我在做:

    snd_ctl_event_t event;
    

    给一个 storage size of 'event' isn't known 错误原因 snd_ctl_event_t 显然是一个私下定义的不透明结构。因此,唯一的选择是动态分配。

    1 回复  |  直到 6 年前
        1
  •  3
  •   AnT stands with Russia    6 年前

    由于它是一个不透明的结构,所有这些操作的目的显然是实现一个不透明的数据类型,同时保存所有的“优点”并至少消除一些“缺点”。

    不透明数据类型的一个突出问题是,在标准C中,您基本上被迫在不透明库函数中动态分配它们。在本地隐式声明不透明对象是不可能的。这会对效率产生负面影响,并常常迫使客户机实现额外的资源管理(即,记住在不再需要对象时释放它)。显示不透明对象的确切大小(在本例中通过函数)并依赖于 alloca 分配存储是尽可能接近一个更高效、更无需担心的本地声明。

    阿洛卡

    通常,为了实现相同的技术,不透明对象的大小可能在头文件中作为编译时常量公开。但是,如果这个独立库中的对象大小发生变化,使用函数还有一个额外的好处,即不必重新编译整个项目(如@R)。评论中提到)。


    以前版本的答案(以下几点仍然适用,但显然是次要的):

    这并不完全等同,因为 违反基于作用域的生存期规则。的寿命 阿洛卡 -ed内存扩展到函数的末尾,而局部对象的生存期只扩展到块的末尾。它可能是坏事,也可能是好事,这取决于你如何使用它。

    some_type *ptr;
    
    if (some condition)
    {
      ...
      ptr = /* alloca one object */;
      ...
    }
    else
    {
      ...
      ptr = /* alloca another object */;
      ...
    }
    

    语义上另一个不相关的区别是 memset 将对象的所有字节归零,而 = { 0 } 不能保证将填充字节(如果有的话)归零。如果该对象随后与一些基于二进制的API一起使用(比如发送到压缩的I/O流),这一点可能很重要。