Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it safe to cast a heap allocated pointer to a pointer to a VLA?

If I've got a pointer to some heap allocated space that represents a typical row-major two dimensional array, is it safe to cast this pointer to an equivalent pointer to a VLA for convenient sub-scripting? Example:

//
// Assuming 'm' was allocated and initialized something like:
//
// int *matrix = malloc(sizeof(*matrix) * rows * cols);
//
// for (int r = 0; r < rows; r++) {
//     for (int c = 0; c < cols; c++) {
//         matrix[r * cols + c] = some_value;
//     }
// }
//
// Is it safe for this function to cast 'm' to a pointer to a VLA?
//
void print_matrix(int *m, int rows, int cols) {
    int (*mp)[cols] = (int (*)[cols])m;

    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            printf(" %d", mp[r][c]);
        }
        printf("\n");
    }
}

I've tested the code above. It seems to work, and it makes sense to me that it should work, but is it safe, defined behavior?

In case anyone is wondering, the use case here is I'm receiving data from a file/socket/etc that represents a row-major 2D (or 3D) array and I'd like to use VLA's to avoid manually calculating indexes to the elements.

like image 750
mshildt Avatar asked Jul 30 '14 12:07

mshildt


People also ask

Can a pointer be on the heap?

They can exist on the heap, on the stack, as static variables or anything else you can do with any other type. You can create pointers or references to them.

How to create a pointer in heap in c++?

Pointing to the heap in C/C++ A pointer is a memory address. In C/C++, you use an asterisk * to create a pointer.

How do you declare a pointer on the heap?

You can declare a pointer and have it point to (make its value be) that location in memory for the variable called count as follows: int *ptr; ptr = &count; The asterisk (*) in a declaration defines to the system that ptr is to be a pointer and the int is the data type to which it will point.


1 Answers

The behaviour is undefined if cols is 0 or smaller. C11 made support for VLAs optional (see e.g. here, and you tagged your question C99, where they’re required), if they’re not supported, the macro __STDC_NO_VLA__ is defined to 1 (cf. C11 6.10.8.3 p1).

This aside, you’re safe.

Thanks to Ouah and Alter Mann!

like image 66
mafso Avatar answered Oct 02 '22 00:10

mafso