概述
长度为0的数组在标准c和c++中是不合法的,但是在gcc中是可行的。
长度为0数组它的最典型的用法就是位于结构体中的最后一项。
使用方式
如下面的例子,分别使用长度为0的数组和指针声明结构体,实现可变长度的数组功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
#include <stdio.h> #include <stdlib.h> struct test1 { int a; int b[0]; }; struct test2 { int a; int *b; }; struct test3 { int a; int reserved; //占位符,64位系统中保证结构体字节对齐,test2中是由编译器对齐的,所以两个结构体占用空间相同 int *b; }; int main() { struct test1 *var1; struct test2 *var2; int iLength = 10; int i; printf ( "the length of struct test1:%d\n" , sizeof ( struct test1)); printf ( "the length of struct test2:%d\n" , sizeof ( struct test2)); printf ( "the length of struct test3:%d\n" , sizeof ( struct test3)); var1=( struct test1*) malloc ( sizeof ( struct test1) + sizeof ( int ) * iLength); var1->a=iLength; for (i=0; i < var1->a; i++) { var1->b[i]=i; printf ( "var1->b[%d]=%d\t" , i, var1->b[i]); } printf ( "\n" ); printf ( "p var1 = %p\n" , var1); printf ( "p var1->a %p\n" , &var1->a); printf ( "var1->b %p\n" , var1->b); printf ( "p var1->b %p\n" , &var1->b); printf ( "p var1->b[0] %p\n" , &var1->b[0]); printf ( "p var1->b[1] %p\n" , &var1->b[1]); printf ( "\n\n" ); var2=( struct test2*) malloc ( sizeof ( struct test2)); var2->a=iLength; var2->b=( int *) malloc ( sizeof ( int ) * iLength); for (i=0; i < var2->a; i++) { var2->b[i]=i; printf ( "var2->b[%d]=%d\t" , i, var2->b[i]); } printf ( "\n" ); printf ( "p var2 = %p\n" , var2); printf ( "p var2->a %p\n" , &var2->a); printf ( "var2->b %p\n" , var2->b); printf ( "p var2->b %p\n" , &var2->b); printf ( "p var2->b[0] %p\n" , &var2->b[0]); printf ( "p var2->b[1] %p\n" , &var2->b[1]); free (var1); free (var2->b); free (var2); return 0; } |
64位linux系统中运行结果
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
the length of struct test1:4 the length of struct test2:16 the length of struct test3:16 var1->b[0]=0 var1->b[1]=1 var1->b[2]=2 var1->b[3]=3 var1->b[4]=4 var1->b[5]=5 var1->b[6]=6 var1->b[7]=7 var1->b[8]=8 var1->b[9]=9 p var1 = 0x55eb1a7d7670 p var1->a 0x55eb1a7d7670 var1->b 0x55eb1a7d7674 p var1->b 0x55eb1a7d7674 p var1->b[0] 0x55eb1a7d7674 p var1->b[1] 0x55eb1a7d7678 var2->b[0]=0 var2->b[1]=1 var2->b[2]=2 var2->b[3]=3 var2->b[4]=4 var2->b[5]=5 var2->b[6]=6 var2->b[7]=7 var2->b[8]=8 var2->b[9]=9 p var2 = 0x55eb1a7d76b0 p var2->a 0x55eb1a7d76b0 var2->b 0x55eb1a7d76d0 p var2->b 0x55eb1a7d76b8 p var2->b[0] 0x55eb1a7d76d0 p var2->b[1] 0x55eb1a7d76d4 |
使用长度为0的数组可以比指针更方便地进行内存的管理。
结构体test1在分配内存时,则是采用一次分配的原则,一次性将所需的内存全部分配给它,释放也是一次释放。数组和结构体的内存是连续的。
结构体test2在分配内存时,需采用两步:首先,需为结构体分配一块内存空间;其次再为结构体中的成员变量分配内存空间。这样两次分配的内存是不连续的,需要分别对其进行管理。当使用长度为0的数组时,则是采用一次分配的原则,一次性将所需的内存全部分配给它。相反,释放时也是一样的。
总结
长度为0的数组并不占有内存空间,而指针方式需要占用内存空间。
对于长度为0的数组,在申请内存空间时,采用一次性分配的原则进行;对于包含指针的结构体,才申请空间时需分别进行,释放时也需分别释放。
对于长度为0的数组元素的访问可正常采用数组方式进行。
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注服务器之家的更多内容!
原文链接:https://blog.csdn.net/zzy570384336/article/details/120718203