Wrap alloca function in C

327 Views Asked by At

Is it possible to wrap the C function alloca into "another"? (only macros of course)

Something like:

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

I'm not quite sure about this, does the extension 6.1 Statements and Declarations in Expressions create a new stack frame? (It kinda looks so because of the curly brackets)

EDIT:

It did some testing on it:

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

Output:

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

The alloca() function allocates size bytes of space in the stack frame of the caller

So, is this above approach safe?

2

There are 2 best solutions below

0
On BEST ANSWER

Got a solution for my problem :)

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

I doubt you can, but more importantly, why would you want to? This is a serious bug!

You'd be allocating something on the stack to have it destroyed on the stack the very same instruction you return it! It would almost certainly be overwritten on the stack before you ever had a chance to use it.