Search code examples
cmemorygnualloca

Wrap alloca function in C


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?


Solution

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