C语言可变长度数组

最近又开始为现在的项目搞服务器压力测试,又捡起之前的LoadRunner。由于要加入更多的逻辑,所以一定程度上抛弃了原先的录制消息的方式,更多地使用protobuff构建和解析消息。从C#和Lua突然转换到C语言,感觉像是从现代化21世纪回到了蛮荒时代,各种读写内存和指针操作,又很是原汁原味贴近自然。

用C搞了一个支持变长的数组:

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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#ifndef _V_ARRAY_H
#define _V_ARRAY_H

#include <stdio.h>
#include <tchar.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
int size;
int* data;
}VArray;

VArray* VArrayInit(int len)
{
VArray* t = (VArray*)malloc(sizeof(VArray));
t->size = len;
t->data = (int*)malloc(len *sizeof(int));

// init with 0
memset(t->data,0,len *sizeof(int));
return t;
}

void VArrayFree(VArray* t)
{
free(t->data);
t->data = NULL;
free(t);
t = NULL;
}


void VArrayResize(VArray* t, int len)
{
if(len == t->size)
return;
else
{
// keep old
int dataLenToKeep = (len < t->size? len : t->size) * sizeof(int);
int* tmpData = (int*)malloc(dataLenToKeep);
memcpy(tmpData, t->data, dataLenToKeep);

// create new
free(t->data);
t->data = (int*)malloc(len *sizeof(int));

// copy to new
memcpy(t->data, tmpData, dataLenToKeep);

// init raw part
if(len > t->size)
memset(t->data + t->size , 0, len *sizeof(int) - dataLenToKeep);

// assign new length
t->size = len;

// free temp
free(tmpData);
}

}


void VArrayPrint(VArray* t)
{
int i = 0;
if(NULL != t)
{
printf("[ ");
for (i = 0 ; i < t->size; i++)
{
printf("%d ",t->data[i]);
}
printf("]\n");
}
}


#endif

还有一种方式是在定义结构体时这么搞:

1
2
3
4
5
typedef struct
{
int size;
int[0] data;
}VArray;

data声明成为一个长度为0的数组。在为其分配内存和释放内存时就比较简单了:

1
2
3
4
5
6
// 分配内存
VArray* t = (VArray*)malloc(sizeof(VArray) + sizeof(int) * size);
// ...
// 销毁
free(t);
t = NULL;

内存分配的是连续整块的,但是如果调整尺寸(Resize)就会不太方便,不能分别处理。