Flexible Array 柔性数组
06 April 2014
##概述 柔性数组(flexible array)分配一段连续的的内存,减少内存的碎片化,简化内存的管理
##柔性数组用途
- Socket通信数据包的传输
- 解析数据包
##测试
###源文件
#include <iostream>
#include <string.h>
#include <memory.h>
#include <stdlib.h>
using namespace std;
const int BUF_SIZE = 100;
typedef struct ScaleArray1
{
int cnt;
char *pBuf;
}SArray1, *pSArray1;
typedef struct ScaleArray2
{
int cnt;
char pBuf[0];
}SArray2, *pSArray2;
typedef struct ScaleArray3
{
int cnt;
char pBuf[1];
}SArray3, *pSArray3;
int main()
{
//赋值用
const char* tmp_buf = "abcdefghijklmnopqrstuvwxyz";
int ntmp_buf_size = strlen(tmp_buf);
//<1>注意s_one 与s_two的大小的不同
cout<< "sizeof(SArray1) = " << sizeof(SArray1) << endl; //8
cout<< "sizeof(SArray2) = " << sizeof(SArray2) << endl; //4
cout<< "sizeof(SArray3) = " << sizeof(SArray3) << endl;//5-->8结构体对齐
cout<< endl;
//为buf分配100个字节大小的空间
int ntotal_stwo_len = sizeof(SArray2) + (1 + ntmp_buf_size) * sizeof(char);
int ntotal_sthree_len = sizeof(SArray3) + ntmp_buf_size * sizeof(char);
//给s_one buf赋值
//******c-style******
pSArray1 pOne= (pSArray1)malloc(sizeof(SArray1));
memset(pOne,0, sizeof(SArray1));
pOne->pBuf = (char*)malloc(1 + ntmp_buf_size);
memset(pOne->pBuf,0, 1 + ntmp_buf_size);
memcpy(pOne->pBuf,tmp_buf, ntmp_buf_size);
//******cpp-style******
//pSArray1 pOne = new SArray1[sizeof(SArray1)];
//pOne->pBuf = new char[1+ntmp_buf_size]();
//memcpy(pOne->pBuf,tmp_buf,ntmp_buf_size);
cout<< "pOne->pBuf = " << pOne->pBuf << endl;
if(NULL != pOne->pBuf)
{
//free(p_sone->s_one_buf);
delete []pOne->pBuf;
pOne->pBuf = NULL;
if(NULL != pOne)
{
//free(p_sone);
delete []pOne;
pOne= NULL;
}
cout<< "free(pOne) successed!" << endl;
}
//给s_two buf赋值
//******c-style******
pSArray2 pTwo = (pSArray2)malloc(ntotal_stwo_len);
memset(pTwo,0, ntotal_stwo_len);
memcpy((char*)(pTwo->pBuf),tmp_buf, ntmp_buf_size);
//******cpp-style******
//pSArray2 pTwo = reinterpret_cast<pSArray2>(new char[ntotal_stwo_len]);
//memcpy((char*)(pTwo->pBuf), tmp_buf, ntmp_buf_size);
cout<< "pTwo->pBuf = " << pTwo->pBuf << endl;
if(NULL != pTwo)
{
//free(p_stwo);
delete [] pTwo;
pTwo = NULL;
cout<< "free(pTwo) successed!" << endl;
}
//给s_three_buf赋值 //******c-style******
pSArray3 pThree = (pSArray3)malloc(ntotal_sthree_len);
memset(pThree,0, ntotal_sthree_len);
memcpy((char*)(pThree->pBuf), tmp_buf, ntmp_buf_size);
//******cpp-style******
//pSArray3 pThree = reinterpret_cast<pSArray3>(new char[ntotal_sthree_len]);
//memcpy((char*)(pThree->pBuf), tmp_buf, ntmp_buf_size);
cout<< "pThree->pBuf = " << pThree->pBuf << endl; //不用加偏移量,直接拷贝!
if(NULL != pThree)
{
//free(p_sthree);
delete [] pThree;
pThree = NULL;
cout<< "free(p_sthree) successed!" << endl;
}
return 0;
}
###makefile
main: scale_array.o g++ scale_array.o -o main
scale_array.o: scale_array.cpp
g++ -c scale_array.cpp
###运行
- vim scale_array.cpp 打开源文件
:make
编译:cw
查看编译结果:!./main
查看执行结果
###三种方式对比
- 存储大小方面:Scale_Array2的存储较Scale_Array1、ScaleArray3都要少,[0]的好处,即用指针的方式需要多开辟存储空间的。
- 数据连续存储方面:ScaleArray1明显数据域是单独开辟的空间,与前的cnt不在连续的存储区域,而ScaleArray2,ScaleArray3则在连续的存储空间下。
- 释放内存方面:显然ScaleArray1的指针的方式,需要先释放数据域部分,才能释放指向结构体的指针变量;而ScaleArray2,ScaleArray3可以直接释放。
##编译器支持 C89 不支持这种东西,C99 把它作为一种特例加入了标准。但是,C99 所支持的是 incomplete type,而不是 zero array,形同 int item[0];这种形式是非法的,C99 支持的形式是形同 int item[];只不过有些编译器把 int item[0];作为非标准扩展来支持,而且在 C99 发布之前已经有了这种非标准扩展了,C99 发布之后,有些编译器把两者合而为一了。