C语言的“动态数组”和“变长数组”

掩码结构体宏的实现本质上就是使用一个掩码数组 chMask 把结构体保护起来。见《大佬的PLOOC使用示例及其基于C语言的面向对象编程-傻孩子.pdf》

 1 /* 公众号:嵌入式大杂烩 */
 2 #ifndef __DYNAMIC_ARRAY_H
 3 #define __DYNAMIC_ARRAY_H
 4  
 5 /* 结构体“重命名” */
 6 typedefstruct dynamic_array dynamic_array_def;
 7  
 8 /* 初始化dynamic_array */
 9 dynamic_array_def *DA_Init(void);
10  
11 /* 销毁dynamic_array */
12 voidDA_Clean(dynamic_array_def *pThis);
13  
14 /* 设置dynamic_array长度 */
15 voidDA_SetSize(dynamic_array_def *pThis, unsigned len);
16  
17 /* 获取dynamic_array长度 */
18 unsignedDA_GetSize(dynamic_array_def *pThis);
19  
20 /* 设置dynamic_array某元素的值 */
21 intDA_SetValue(dynamic_array_def *pThis, unsigned index, int value);
22  
23 /* 获取dynamic_array某元素的值 */
24 intDA_GetValue(dynamic_array_def *pThis, unsigned index, int *pValue);
25  
26 #endif
dynamic_array.h
 1 /* 公众号:嵌入式大杂烩 */
 2 #include "dynamic_array.h"
 3 #include <stdlib.h>
 4  
 5 /* 创建一个动态数组结构体模板 */
 6 struct dynamic_array
 7 {
 8     int*array;
 9     unsigned len;
10 };
11  
12 /* 初始化dynamic_array */
13 dynamic_array_def *DA_Init(void)
14 {
15     dynamic_array_def *pArray =malloc(sizeof(dynamic_array_def));
16  
17     pArray->array=NULL;
18     pArray->len =0;
19 }
20  
21 /* 销毁dynamic_array */
22 voidDA_Clean(dynamic_array_def *pThis)
23 {
24     free(pThis->array);
25     pThis->len =0;
26     free(pThis);
27 }
28  
29 /* 设置dynamic_array长度 */
30 voidDA_SetSize(dynamic_array_def *pThis, size_t len)
31 {
32     pThis->len = len;
33     pThis->array=(int*)realloc(pThis->array, pThis->len*sizeof(int));
34 }
35  
36 /* 获取dynamic_array长度 */
37 size_tDA_GetSize(dynamic_array_def *pThis)
38 {
39     return pThis->len;
40 }
41  
42 /* 设置dynamic_array某元素的值 */
43 intDA_SetValue(dynamic_array_def *pThis, size_t index, int value)
44 {
45     if(index > pThis->len)
46     {
47         return-1;
48     }
49  
50     pThis->array[index]= value;
51     return0;
52 }
53  
54 /* 获取dynamic_array某元素的值 */
55 intDA_GetValue(dynamic_array_def *pThis, size_t index, int *pValue)
56 {
57     if(index > pThis->len)
58     {
59         return-1;
60     }
61  
62     *pValue = pThis->array[index];
63     return0;
64 }    
dynamic_array.c

 变长数组VLA(数组的长度由变量确定):

  为何要引入VLA:定长数组使用方便, 但是却浪费空间; 指针形式【动态数组】只多使用了一个指针的空间, 不会造成大量空间分浪费, 但是使用起来需要多次分配, 多次释放,忘记释放就会内存泄漏。

  变长数组是 C99 标准新增的特性,它允许数组的长度不是固定的编译时常量,而是根据程序运行时的变量或表达式来决定,特别适合需要动态大小的局部数组[如数据包长度不定的解析函数中,局部变量数组】场景。注意:需要检查数组的长度不能为0或负数。

  在标准的C/C++中不允许0长度数组,而在GNU C中可以(是GNU的扩展。C99之间 定义时长度为arry[0];C99或之后可以留空arry[]).变成数组可以节约空间,解决使用数组时内存的冗余和数组的越界问题。但也有一个缺点就是结构体中的变长数组【只能放在结构体的最后面】。

1 typedef struct {
2     int len;
3     //int array[];/*!!!变长数组只能放在结构体的最后面*/
4     int CRC;
5     int array[0];/*C99为int array[]*/
6 }SoftArray;
结构体中的变长数组

  

 1 #include <stdio.h>
 2 void sum_array(int size) {
 3     int arr[size]; // 变长数组,调用时确定
 4     for (int i = 0; i < size; i++) {
 5         arr[i] = i * 2;
 6     }
 7     int sum = 0;
 8     for (int i = 0; i < size; i++) {
 9         sum += arr[i];
10     }
11     printf("数组元素之和:%d\n", sum);
12 }
13 int main() {
14     int n;
15     printf("请输入数组大小:");
16     scanf("%d", &n);
17     sum_array(n);
18     return 0;
19 }
变长数组

1) 优点

  • 简单易用:无需手动分配和释放内存。
  • 局部优化:栈上分配通常比堆上分配更快。
  • 动态性:无需提前知道固定大小。

2) 局限性

  • 栈空间限制:栈大小有限(通常几 MB),过大的变长数组会导致栈溢出。
  • 仅限局部:不能声明为全局变量或静态变量。
  • 兼容性:C11 将 VLA 设为可选特性,部分编译器可能不支持。

注意事项

  • 大小检查:确保长度不为负数或零,避免未定义行为。
  • 栈溢出:避免声明过大的变长数组,例如 int arr[1000000] 可能崩溃。
  • 编译器支持:使用前确认编译器支持 C99 或更高版本(如 gcc 使用 -std=c99

 

      

posted on 2025-10-11 15:37  杰瑞鼠  阅读(64)  评论(0)    收藏  举报