将堆分配的指针强制转换为指向VLA的指针是否安全?

msh*_*ldt 6 c arrays pointers c99 language-lawyer

如果我有一个指向某个堆分配空间的指针,该空间代表一个典型的行主要二维数组,是否可以将此指针强制转换为指向VLA的等效指针以方便子脚本编写?例:

//
// 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

我已经测试了上面的代码.它似乎有效,对我来说它应该有用,但它是安全的,定义的行为吗?

如果有人想知道,这里的用例是我从文件/套接字/等接收代表行主要2D(或3D)数组的数据,我想使用VLA来避免手动计算索引到元素.

maf*_*fso 5

cols如果0 或更小,则行为未定义。C11 使对 VLA 的支持成为可选(参见例如此处,并且您标记了您的问题 C99,其中需要它们\xe2\x80\x99),如果不支持它们\xe2\x80\x99,则宏__STDC_NO_VLA__定义为 1(参见 C11 6.10.8.3 p1)。

\n\n

除此之外,你\xe2\x80\x99 是安全的。

\n\n

感谢 Ouah 和 Alter Mann!

\n

  • @epicbrew,任何也实现 C99 的编译器都可以与 VLA 一起使用。它们被设为可选,是为了让那些还不是 C99 的编译器升级为现代 C。可能只是一厢情愿。 (2认同)