引言
#define MAXLEN 1024
typedef struct kd_node
{
struct kd_node *left;
struct kd_node *right;
int dim;
unsigned long long data[MAXLEN];
}kd_node;
在这段代码中,为了存储数据,申请了长度为1024的unsigned long long型数组,若是数据的长度远远小于MAXLEN,这样设计,及其浪费空间。 在C99标准中给出了新的设计方法,通过柔性数组可以解决这个问题。
struct sd_node
{
int num;
int size;
char data[];
};
我们把数组的大小声明为0,或者不给出大小,称之为柔性数组。(全局数组和局部数组不能这样定义)。
概念
柔性数组是一种数组大小待定的数组。 在C语言中我们可以使用结构体产生柔性数组,结构体的最后一个元素可以是大小未知的数组。 在上面的结构体中,data仅仅是一个待使用的标识符,不占用内存空间,因此sizeof(struct sd_node) = 8; 用途:长度为零的数组的主要用途是为了满足长度可变的结构体。 用法:在结构体的最后,声明一个长度为0的数组,就可以使这个结构体是可变长的,对于编译器而言,长度为0的数组并不占用空间,因为数组名本身不占空间,它只是一个偏移量,数组名这个符号本身代表了一个不可修改的地址常量,但对于这个数组的大小,我们可以进行动态分配。 优点:比起结构体中声明一个指针变量、再进行动态分配的办法,这种方法效率更高。 缺点:在结构体中,数组为0的数组必须在最后声明,对设计结构体类型有一定的限制。
int main()
{
struct sd_node *sp = (struct sd_node*)malloc(sizeof(struct sd_node) + 100);
sp->num = 0;
sp->size = 100;
strcpy(sp->data,"tulunhello");
}
简单应用
假设我们在网络通信过程中使用的数据缓冲区,缓冲区包括num,size,data字段,分别标识数据的块号,长度,和传输的数据,我们有以下设计思路: 定长数据包 定长数据缓冲区,设置一个足够大小MAXSIZE的数据缓冲区。
#define MAXSIZE 4096
struct data buffer
{
int num;
int size;
char data[MAXSIZE];
}
然而使用定长数组作为数据缓冲区,为了避免造成缓冲区溢出,数组设置就大开小用了,而实际使用过程中,达到MAXSIZE长度的数据很少。多数情况,缓冲区大部分都浪费了。 指针数据包
struct data buffer *pbuff = (struct data_buffer*)malloc(sizeof(struct data_buffer));
if(NULL == pbuff) exit(1);
pbuff->size = CURSIZE
pbuff->data = (char*)malloc(sizeof(char) * CURSIZE);
if(NULL == pbuff) exit(1);
使用指针结果作为缓冲区,多使用了一个指针大小的空间,不需要使用MAXSIZE长度的数组,不会造成空间的大量浪费,但是开辟空间时,需要额外开辟数据域空间。释放的时候也需要显示释放数据域的空间。但是我们在实际使用过程中,往往是在函数中开辟空间,然后返回给使用者指向struct point_buffer的指针,这时候我们并不能假定使用者了解我们开辟的细节,并按照约定的操作释放空间,甚至会造成内存泄漏。 变长数据缓冲区 柔性数组:既不会造成空间的浪费,使用的时候也只需要开辟一次空间。
struct data_buff
{
int num;
int size;
char data[];
};
int main()
{
int n = strlen("hello") + 1;
struct data_buff *pbuff = (struct data_buff*)malloc(sizeof(struct data_buffer) + sizeof(char) * n);
if(NULL == puff) exit(1);
pbuff->num = 1;
pbuff->size = n;
memcpy(pbuff->data,"hello",n);
free(pbuff);
return 0;
}
说明
//只计算num大小,不计算柔性数组
struct Node_A
{
int num;
int data[];
};
struct Node_B
{
int num;
int data[3];
};
int main()
{
struct Node_A ar = {8,{1,2,3,4,5,6,7,8}};
struct Node_B br = {3,{1,2,3}};
int sizea = sizeof(ar);
int sizeb = sizeof(br);
printf("%d %d\n",sizeof(ar),sizeof(br));
printf("%d\n",ar.data[0]);
}
动态构建二维数组
int main()
{
int row,col;
int **ip = NULL;
printf("input row col size: \n");
scanf("%d %d",&row,&col);
ip = (int**)malloc(sizeof(int*) * row);
if(NULL == ip) exit(1);
for(int i = 0;i < row;i++)
{
ip[i] = (int*)malloc(sizeof(int) * col);
if(NULL == ip[i])
{
exit(1);
}
}
for(int i = 0;i < row;i++)
{
for(int j = 0;j < col;j++)
{
ip[i][j] = i + j;
}
}
for(int i = 0;i < row;i++)
{
for(int j = 0;j < col;j++)
{
printf("%5d",ip[i][j]);
}
printf("\n");
}
printf("\n");
for(int i = 0;i < row;++i)
{
free(ip[i]);
ip[i] = NULL;
}
free(ip);
ip = NULL;
return 0;
}
|