有关变长数组(VLA)(转)

原链接:http://blog.chinaunix.net/uid-24347760-id-1989578.html

在突然听到这个名词后,在网上搜的。

1. 变长数组是分配在堆栈上的, 其实从语义的角度也应该是这样, 变长数组还是一个数组, 还是一个局部变量, 在c语言中, 
局部变量是分配在堆栈上的, malloc才是分配在堆上面的. 这里面没有不存在什么 
内存泄漏, 因为堆栈上的内存是不需要程序员管理的 
  
2. 变长数组和其他变量共同存在于一个作用域之内时, 变长数组是在最后分配的, 
也就是处在堆栈的最下面(地址最低). 这也是变长数组不同于普通变量的情况, 
普通变量的内存分配是按照定义顺序来的, 先定义的先分配, 但是变长数组不是这样的, 
在一个作用域内变长数组都是放到最后分配的, 原因很简单, 变长数组的大小在编译时无 
法确定, 所以如果在变长数组后面分配普通变量的空间, 那么对后面普通变量的存取就不 
方便了,当然简单的情况可以通过优化解决, 但是如果有很多的变量数组和普通变量混合 
在一起的话,优化很难做到很好, 所以把变长数组都放在最后面分配, 是一个比较合理的 
办法; 
当然, 不是说一定要放在最后, 按照普通的定义顺序来分配空间也是可以的,只是在存取 
可变数组后面的变量的时候, 需要首先找到可变数组的起始地址, 然后再往下(低地址) 
找到后面变量的地址, 存取相应的变量.我目前所使用的gcc放到最后的做法, 也可以理解 
成一种优化. 
  
  
3. 对变长数组的元素存取, 可以把首地址放在寄存器里面, 也可以在把首地址放在堆栈 
里面,然后存取元素的时候先取出首地址, 然后在通过偏移量的方式存取里面的元素. 
  
4.变长数组不能在静态存储区中, 这个很显然, 静态存储区在编译时就确定分配内存的 
大小,不像堆栈一样是动态的, 变长数组显然不能定义在静态存储区中.

5. 变长数组的意义, 我觉得在c里面还是有一些意义, 如果是在对性能,内存要求十分严 
格的地方, 允许声明变长数组还是比较方便的, 因为原来需要一块连续内存的地方要么 
声明的大一些,保证肯定够用, 但这样就浪费了, 在对内存要求严格的地方就不好了, 
另外一种做法就是malloc动态分配, 但是这样的缺点是需要手动管理, 要手动free, 
程序如果大的话内存管理不好的话容易内存泄漏,所以在c里面还是有一些意义. 
但是在c++里面已经有vector了, 而且c++也不太多应用在对性能,内存要求非常高的地方, 
  
6.使用变长数组, 最重要的当然是要检查数组的size的合法性了, 
我前面举例为了减少干扰因素, 都没有做检查, 实际的程序肯定要做这个检查。
另外, 就是又多了一种堆栈溢出的方法,数组大小如果是负的话又可以跳到不该跳到 
的地方了

有关变长数组(VLA)(转)

时间: 2024-10-28 23:44:10

有关变长数组(VLA)(转)的相关文章

C99新增内容之变长数组(VLA)

我们在使用多维数组是有一点,任何情况下只能省略第一维的长度.比如在函数中要传一个数组时,数组的行可以在函数调用时传递,当属数组的列却只能在能被预置在函数内部.看下面一个例子: #define COLS 4 int sum2d(int ar[][COLS],int rows) { int r; int c; int tot=0; for(r=0;r<rows;r++) for(c=0;c<COLS;c++) tot+=ar[r][c]; return tot; } 现在假设定义了如下数组: in

变长数组(variable-length array,VLA)

处理二维数组的函数有一处可能不太容易理解,数组的行可以在函数调用的时候传递,但是数组的列却只能被预置在函数内部.例如下面这样的定义: 1 #define COLS 4 2 int sum3d(int ar[][COLS], int rows) 3 { 4 int r, c, tot; 5 tot = 0; 6 7 for(r = 0; r < rows; r++) 8 for(c = 0; c < COLS; c++) 9 tot += ar[r][c]; 10 return tot; 11

变长数组 - 转

http://ericwang.github.io/program/2010/02/10/c_Variable_length_arrays/ C中的Variable length arrays (变长数组) Variable length arrays 是C99的特性,而不是 C++98 的,关于c99标准的变长数组, 在标准的6.7.5.2 Array declarators里面有这样的说明: 2.Only ordinary identifiers (as defined in 6.2.3)

变长数组_相乘取结果

//变长数组 相乘取结果 #include <stdio.h> int main(void){ // int array_01[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; int array_02[4][3] = {12,11,10,9,8,7,6,5,4,3,2,1}; int result[3][3] = {0}; int i, j, k; for (i = 0; i < 3; i ++){ //遍历array_01数组元素 for (j = 0;j

C之变长数组

变长数组是C99标准新加入的一个特性,它的加入大大方便了我们的编程,所谓变长数组,不是数组的长度可变,而是指允许使用变量来定义数组.这可以使我们写出更具通用性的函数.下面是一个例子,函数sum2d完成将一个二位数组中的所有数值相加并返回其和. #include<stdio.h> #define SIZE 10 #define LOC 2 #define ROW 4int sum2d(int loc, int row, int num[loc][row]); int main(void){ in

C 语言变长数组 struct 中 char data[0] 的用法

1.结构体内存布局(padding) 为了让CPU能够更舒服地访问到变量,struct中的各成员变量的存储地址有一套对齐的机制.这个机制概括起来有两点:第一,每个成员变量的首地址,必须是它的类型的对齐值的整数倍,如果不满足,它与前一个成员变量之间要填充(padding)一些无意义的字节来满足:第二,整个struct的大小,必须是该struct中所有成员的类型中对齐值最大者的整数倍,如果不满足,在最后一个成员后面填充. The following typical alignments are va

(变长数组)变量也可做特殊数组的长度

这个问题困扰我好久,终于完美区分: 看一个例子: main() { int n=10; int a[n]; scanf("%d",&a[2]); printf("%d",a[2]); system("pause"); } 以上例子中,n明显是一个整型的变量,虽然付了值,但是他仍然不可做为数组的大小,按理说是编译不通过的,但有些编译器,却让着个编译过了, 我们说:因为定义数组时,分配空间是需要一个固定的值,来确定你所申请的空间的大小. 若i

变长数组与函数参数

代码: #include <stdio.h> #include <stdlib.h> void setval(const size_t, const size_t, int arr[*][*]); void display(const size_t, const size_t, int arr[*][*]); int main(void) { const size_t ROWS = 5; const size_t COLS = 3; int arr[ROWS][COLS]; set

c语言,变长数组

C语言变长数组data[0][总结]: char data[0]用法总结: