何时在C中使用可变长度数组,但何时使用动态分配?
我在C99中发现了可变长度数组,但看起来它的行为与malloc+free几乎相同 我发现的实际差异是:何时在C中使用可变长度数组,但何时使用动态分配?,c,arrays,malloc,free,c99,C,Arrays,Malloc,Free,C99,我在C99中发现了可变长度数组,但看起来它的行为与malloc+free几乎相同 我发现的实际差异是: 太大的阵列处理: unsigned size = 4000000000; int* ptr = malloc(size); // ptr is 0, program doesn't crash int array[size]; // segmentation fault, program crashes 内存泄漏:仅在动态阵列分配中可能: int* ptr = malloc(size);
unsigned size = 4000000000;
int* ptr = malloc(size); // ptr is 0, program doesn't crash
int array[size]; // segmentation fault, program crashes
int* ptr = malloc(size);
...
if(...)
return;
...
free(ptr);
- 还有什么区别(我对实用建议感兴趣)
- 对于可变长度数组的两种方式,程序员还有什么问题
- 何时选择VLA,何时选择动态阵列分配
- 什么更快:VLA或malloc+免费
- VLA实际上位于空间有限的堆栈上,而
及其朋友在堆上分配,这可能允许更大的分配。此外,您对该过程有更多的控制,因为malloc()
如果失败,可能会返回malloc()
。换句话说,你必须小心VLA,不要在runtine中浪费时间NULL
- 并非所有编译器都支持VLA,例如Visual Studio。此外,作为可选功能,当定义了
宏时,允许不支持它们\uuu STDC\u NO\u VLA\uu
- 一些实用建议:
malloc()
快。当然,malloc()
调用有一些开销,但似乎更重要的是数据访问效率
下面是使用GNU/Linux x86-64和GCC编译器进行的一些快速而肮脏的比较。请注意,结果可能因平台而异,甚至可能因编译器版本而异。您可以使用一些基本的数据访问
malloc()
prime-trial-gen.c
:
然后是第二个程序,它使用生成的“素数字典”:
prime-trial-test.c
:
编译和运行(VLA版本):
正如你所说,π(10**7)
实际上是664579
。请注意,两个执行时间几乎相同。VLAs的一个优点是可以将可变尺寸的数组传递给函数,这在处理(大小相同的)矩阵时非常方便,例如:
int n = 4;
int m = 5;
int matrix[n][m];
// …code to initialize matrix…
another_func(n, m, matrix);
// No call to free()
其中:
void another_func(int n, int m, int matrix[n][m])
{
int sum = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
// …use matrix just like normal…
sum += matrix[i][j];
}
}
// …do something with sum…
}
以及:
void另一个函数2(int n,int m,int*矩阵)
{
整数和=0;
对于(int i=0;i
指针向量
int n=4;
int m=5;
int**matrix=malloc(sizeof(*matrix)*n);
对于(int i=0;i
以及:
void另一个函数3(int n,int m,int**matrix)
{
整数和=0;
对于(int i=0;i
此表单可优化为两种分配:
int n = 4;
int m = 5;
int **matrix = malloc(sizeof(*matrix) * n);
int *values = malloc(sizeof(*values) * n * m);
for (int i = 0; i < n; i++)
matrix[i] = &values[i * m];
// …code to initialize matrix…
another_func2(n, m, matrix);
free(values);
free(matrix);
int n=4;
int m=5;
int**matrix=malloc(sizeof(*matrix)*n);
int*值=malloc(sizeof(*值)*n*m);
对于(int i=0;i
优势弗拉
当您使用VLA时,需要做的簿记工作更少。但是如果您需要处理大小荒谬的数组,malloc()
仍然会得分。如果您小心的话,您可以将VLA与malloc()
等一起使用-例如,请参见。与malloc()
一起使用,code与VLA不同,它知道OOM。
$ gcc -O2 -std=c99 -pedantic -Wall -W prime-trial-test.c
$ time ./a.out
pi(10 000 000) = 664579
real 0m1.930s
user 0m1.903s
sys 0m0.013s
$ gcc -DWANT_VLA=1 -O2 -std=c99 -pedantic -Wall -W prime-trial-test.c
ime ./a.out
pi(10 000 000) = 664579
real 0m1.929s
user 0m1.907s
sys 0m0.007s
int n = 4;
int m = 5;
int matrix[n][m];
// …code to initialize matrix…
another_func(n, m, matrix);
// No call to free()
void another_func(int n, int m, int matrix[n][m])
{
int sum = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
// …use matrix just like normal…
sum += matrix[i][j];
}
}
// …do something with sum…
}
int n = 4;
int m = 5;
int *matrix = malloc(sizeof(*matrix) * n * m);
// …code to initialize matrix…
another_func2(n, m, matrix);
free(matrix);
void another_func2(int n, int m, int *matrix)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
// …do manual subscripting…
sum += matrix[i * m + j];
}
}
// …do something with sum…
}
int n = 4;
int m = 5;
int **matrix = malloc(sizeof(*matrix) * n);
for (int i = 0; i < n; i++)
matrix[i] = malloc(sizeof(matrix[i] * m);
// …code to initialize matrix…
another_func2(n, m, matrix);
for (int i = 0; i < n; i++)
free(matrix[i]);
free(matrix);
void another_func3(int n, int m, int **matrix)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
// …use matrix 'just' like normal…
// …but there is an extra pointer indirection hidden in this notation…
sum += matrix[i][j];
}
}
// …do something with sum…
}
int n = 4;
int m = 5;
int **matrix = malloc(sizeof(*matrix) * n);
int *values = malloc(sizeof(*values) * n * m);
for (int i = 0; i < n; i++)
matrix[i] = &values[i * m];
// …code to initialize matrix…
another_func2(n, m, matrix);
free(values);
free(matrix);