Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在堆上创建可变长度数组?_C_Dynamic Memory Allocation_Calloc_Variable Length Array - Fatal编程技术网

C 如何在堆上创建可变长度数组?

C 如何在堆上创建可变长度数组?,c,dynamic-memory-allocation,calloc,variable-length-array,C,Dynamic Memory Allocation,Calloc,Variable Length Array,我使用C的可变长度数组实现了一个算法: int matrix[rows][cols]; 我成功地测试了它在荒谬的维度上是否失败。有没有办法在堆上而不是堆栈上分配这个矩阵?否则,我将不得不将其重写为int** 类似于calloc(sizeof(int[rows][cols]),1)?注意,这个问题是关于可变长度数组的。看起来很简单。唯一一个远程棘手的问题是用于保存指向动态分配数组的指针的类型: #include <stdlib.h> #include <stdio.h>

我使用C的可变长度数组实现了一个算法:

int matrix[rows][cols];
我成功地测试了它在荒谬的维度上是否失败。有没有办法在堆上而不是堆栈上分配这个矩阵?否则,我将不得不将其重写为
int**


类似于
calloc(sizeof(int[rows][cols]),1)
?注意,这个问题是关于可变长度数组的。

看起来很简单。唯一一个远程棘手的问题是用于保存指向动态分配数组的指针的类型:

#include <stdlib.h>
#include <stdio.h>

static void print_matrix(int r, int c, int matrix[r][c])
{
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            printf(" %d", matrix[i][j]);
        putchar('\n');
    }
}

static void set_matrix(int r, int c, int matrix[r][c])
{
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            matrix[i][j] = (i+1) * 100 + j + 1;
    }
}

int main(void)
{
    size_t rows = 9;
    size_t cols = 7;
    size_t size = sizeof(int[rows][cols]);
    printf("rows = %zu, cols = %zu, size = %zu\n", rows, cols, size);
    int (*matrix)[cols] = calloc(sizeof(int[rows][cols]), 1);
    if (matrix != 0)
    {
        set_matrix(rows, cols, matrix);
        print_matrix(rows, cols, matrix);
        free(matrix);
    }
    return 0;
}

看起来很简单。唯一一个远程棘手的问题是用于保存指向动态分配数组的指针的类型:

#include <stdlib.h>
#include <stdio.h>

static void print_matrix(int r, int c, int matrix[r][c])
{
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            printf(" %d", matrix[i][j]);
        putchar('\n');
    }
}

static void set_matrix(int r, int c, int matrix[r][c])
{
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
            matrix[i][j] = (i+1) * 100 + j + 1;
    }
}

int main(void)
{
    size_t rows = 9;
    size_t cols = 7;
    size_t size = sizeof(int[rows][cols]);
    printf("rows = %zu, cols = %zu, size = %zu\n", rows, cols, size);
    int (*matrix)[cols] = calloc(sizeof(int[rows][cols]), 1);
    if (matrix != 0)
    {
        set_matrix(rows, cols, matrix);
        print_matrix(rows, cols, matrix);
        free(matrix);
    }
    return 0;
}

您可以创建指向VLA的指针:

size_t rows, cols;
... // get values for rows and cols
T (*arr)[cols] = malloc( sizeof (T [cols]) * rows );
if ( arr )
{
  ...
  arr[i][j] = some_value; 
  ...
}
关于是否

T (*arr)[cols] = malloc( sizeof *arr * rows );
应该有用。按照标准的措辞方式,此表单会导致未定义的行为,因为
sizeof
必须在运行时计算
*arr
(因为表达式
*arr
指的是VLA),
arr
在计算
sizeof*arr
时是无效的指针

然而,这取决于“评估”在特定语境中的含义;与固定长度数组相比,无需取消对
arr
的引用以确定它所指向的数组的大小:

T (*arr)[10] = malloc( sizeof *arr * rows ); 
我和其他一些人认为,该标准在这方面措词不当,无论
arr
指向固定长度数组还是可变长度数组,
sizeof*arr
都应该有效。这是我使用的习惯用语,它还没有在我身上失败


但是,如果我没有指出这个问题,并提供一些我知道不会导致UB的东西,我将是失职的

您可以创建指向VLA的指针:

size_t rows, cols;
... // get values for rows and cols
T (*arr)[cols] = malloc( sizeof (T [cols]) * rows );
if ( arr )
{
  ...
  arr[i][j] = some_value; 
  ...
}
关于是否

T (*arr)[cols] = malloc( sizeof *arr * rows );
应该有用。按照标准的措辞方式,此表单会导致未定义的行为,因为
sizeof
必须在运行时计算
*arr
(因为表达式
*arr
指的是VLA),
arr
在计算
sizeof*arr
时是无效的指针

然而,这取决于“评估”在特定语境中的含义;与固定长度数组相比,无需取消对
arr
的引用以确定它所指向的数组的大小:

T (*arr)[10] = malloc( sizeof *arr * rows ); 
我和其他一些人认为,该标准在这方面措词不当,无论
arr
指向固定长度数组还是可变长度数组,
sizeof*arr
都应该有效。这是我使用的习惯用语,它还没有在我身上失败


但是,如果我没有指出这个问题,并提供一些我知道不会导致UB的东西,我将是失职的

@user3528438我是专门询问可变长度数组数据类型的。另外,5D,真的吗?5D的效果可以简化为2D的效果。您是否尝试了calloc(sizeof(int[rows][cols]),1)?你穿多大号的?实际上,更相关的是打印
cols
sizeof
表达式的值。它能满足你的需要吗?问题是“我应该把结果分配给什么”?@TomášZato 5D?是的,说真的!为什么不呢?@user3528438我误读了另一篇文章,我认为维度是常量(它们是大写的)。这个问题有很多重复的地方。在过去的6个小时里,我今天刚刚看到一个问题。我选择了那个特别的一个,因为1)我用VLA方法回答;2) 5D是一个非常独特的关键字,很容易查找。然而,VLA方法有两个版本:1)使用指向N-D数组的指针;2) 使用指向(N-1)-D数组的指针,并将顶部维度保持为指针。前者的优点是将所有维度的大小记录为指针的类型,后者的优点是具有与常规N-D数组相同的语法,而不是(N+1)-D@user3528438我特别询问可变长度数组数据类型。另外,5D,真的吗?5D的效果可以简化为2D的效果。您是否尝试了calloc(sizeof(int[rows][cols]),1)?你穿多大号的?实际上,更相关的是打印
cols
sizeof
表达式的值。它能满足你的需要吗?问题是“我应该把结果分配给什么”?@TomášZato 5D?是的,说真的!为什么不呢?@user3528438我误读了另一篇文章,我认为维度是常量(它们是大写的)。这个问题有很多重复的地方。在过去的6个小时里,我今天刚刚看到一个问题。我选择了那个特别的一个,因为1)我用VLA方法回答;2) 5D是一个非常独特的关键字,很容易查找。然而,VLA方法有两个版本:1)使用指向N-D数组的指针;2) 使用指向(N-1)-D数组的指针,并将顶部维度保持为指针。前者的优点是将所有维度的大小记录为指针的类型,后者的优点是具有与常规N-D数组相同的语法,而不是(N+1)-DYou可以创建
matrix
使用
int(*matrix)[rows][cols]=malloc(sizeof*matrix)稍微简单一点
然后在调用
set_matrix()
print_matrix()
时使用
*matrix
而不是
matrix
,您可以使用
int(*matrix)[rows][cols]=malloc(sizeof*matrix)]创建
矩阵
稍微简单一点
然后在调用
set\u matrix()
print\u matrix()
时使用
*matrix
而不是
matrix