在C中包装alloca函数



是否可以将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: %pn", "array", array);
    }
    
    {   /* <- creates no new stack frame ? */
        int *array = safeAlloca(sizeof(* array) * 4);
        
        printStackFrameAddr("main");
        
        printf("t%-20s: %pn", "array", array);
    }
    
    return 0;
}
输出:

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

alloca()函数在堆栈中分配大小字节的空间调用者的frame

那么,上述方法安全吗?

我找到了一个解决方案:)

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

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

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

相关内容

  • 没有找到相关文章

最新更新