在 C 中包装 alloca 函数

Posted

技术标签:

【中文标题】在 C 中包装 alloca 函数【英文标题】:Wrap alloca function in C 【发布时间】:2014-07-20 20:13:23 【问题描述】:

是否可以将 C 函数 alloca 包装成“另一个”? (当然只有宏)

类似:

#define my_alloca(size)                                      \
                             (                               \
                                   void *ret = alloca(size);  \
                                   my_function(ret);          \
                             ret;)

对此我不太确定,扩展 6.1 Statements and Declarations in Expressions 是否会创建一个新的堆栈框架? (因为大括号,看起来有点像)

编辑:

它做了一些测试:

#define printStackFrameAddr(_fnc)   \
    printf("%-20s: %p \n", _fnc, __builtin_frame_address(0))


void _my_init(void *mem)




void *notSafeAlloca(size_t num)

    void *mem;
    
    printStackFrameAddr("notSafeAlloca");
    
    mem = alloca(num);
    
    _my_init(mem);
    
    return mem;


#define safeAlloca(_num)            \
    (                              \
        void *ret = alloca(_num);   \
        _my_init(ret);              \
        printStackFrameAddr("safeAlloca");      \
    ret;)

int main(int argc, const char * argv[])

    printStackFrameAddr("main");
    
    
       /* <- creates no new stack frame ? */
        int *array = notSafeAlloca(sizeof(* array) * 4);
        
        printStackFrameAddr("main");
        
        printf("\t%-20s: %p\n", "array", array);
    
    
       /* <- creates no new stack frame ? */
        int *array = safeAlloca(sizeof(* array) * 4);
        
        printStackFrameAddr("main");
        
        printf("\t%-20s: %p\n", "array", array);
    
    
    return 0;

输出:

main                : 0x7fff5fbff8d0 
notSafeAlloca       : 0x7fff5fbff860 
main                : 0x7fff5fbff8d0 
        array               : 0x7fff5fbff820
safeAlloca          : 0x7fff5fbff8d0 
main                : 0x7fff5fbff8d0 
        array               : 0x7fff5fbff888

alloca() 函数在 堆栈中分配 size 个字节的空间 调用者的框架

那么,以上方法安全吗?

【问题讨论】:

大括号不像堆栈框架In C, do braces act as a stack frame? 您在main() 中的测试尚无定论;很有可能“数组”被优化了,因为它没有被使用。您至少应该打印地址 (printf("%p\n", array);) 看看是否有任何改变。 @JonathanLeffler 不,仍然是相同的堆栈帧地址。 http://***.com/questions/2614561/whats-the-difference-between-allocan-and-char-xn @d3l:没那么简单。出于复合文字、自动变量等的目的,块的末尾确实结束了此类对象的生命周期。 alloca 相当特殊,因为它创建的对象具有与调用函数相关联的生命周期,而不是与块相关联。要问的问题不是大括号是否“创建堆栈框架”,而是“alloca 创建的对象的生命周期是多少?” 【参考方案1】:

为我的问题找到了解决方案:)

void *_my_alloca(void *memory)

    // init memory & stuff

    return memory;


#define my_alloca(_size)   _my_alloca(alloca(_size))

int main(int argc, const char **argv)

    int *array = my_alloca(sizeof(* array) * 4);

【讨论】:

【参考方案2】:

我怀疑你可以,但更重要的是,你为什么要这样做? 这是一个严重的错误!

你会在堆栈上分配一些东西,让它在你返回它的指令中被销毁!在您有机会使用它之前,它几乎肯定会在堆栈上被覆盖。

【讨论】:

我知道这一点,我的问题是关于“6.1 表达式中的语句和声明”是否会创建一个新的堆栈框架。如果不是,那就完全没问题了。

以上是关于在 C 中包装 alloca 函数的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C 或 C++ 中包装参数并将它们传递给 system 或 exec*

在 C 中包装 vector<Mat> 时出现分段错误错误

在命名空间中包装外部库

在Visual C#中包装在Label中的单词的位置

在 PHP 函数中包装 MySQL 查询

如何在 Javascript 中包装函数?