变长数组

来源:互联网 发布:软件著作权 发表状态 编辑:程序博客网 时间:2024/05/01 09:45

之前遇到过这个,当时好像也是明白了,但过后就有点忘记了,或者说思路不清,今天有空写了个博客。

 

我们有这样的需求,比如我们声明了一个结构体变量,SMsg  msg,我们可以直接通过这个变量访问到缓冲区msg.buff对其进行操作,换句话说得找个变量来标识这段缓冲区的地址。


考虑以下情况,我们想声明一个结构体SMsg,这个结构体有以下成员。

1.   msgid  ,int型   用来表示这个结构体的id

2.   buffsize  unsigned int 类型,表示这个结构体的缓冲区大小

3.   buff, 结构体的缓冲区,额,这个声明成什么类型呢???

 

 解决办法:


1.   我们可以声明成一个char *类型

结构体定义如下:

struct SMsg

{

intmsgid;

unsigned intbuffsize;

char *buff;

};

当我想使用一个缓冲区大小是16的这个结构体,我可以这样声明。

SMsg*msg=(SMsg*) malloc(sizeof(SMsg)+16);

msg->buffsize=16;

msg->buff=(char*)malloc(16);

 

想要使用缓冲区内容时,我们可以使用msg->buff 对其进行操作。

而当释放时,我们也必须 free(msg->buff);  free(msg);对其进行释放。

这样有没有觉得很麻烦,确实这样,而且这样容易出错,忘记为buff分配内存,我记得在青岛实训时,有个同学就遇到过这样的问题。

 

2.我们可以改进一下。声明成这样

#define MAX_BUFFER_SIZE1024

struct SMsg

{

      int msgid;

      unsigned int buffsize;

      char buff[MAX_BUFFER_SIZE];

};

这样我们就不必为整个结构体来分配内存了可以这样操作

SMsg *msg=(SMsg*)malloc(sizeof(SMsg));

msg->buffsize=16;

我们可以用msg->buff来访问数据。

使用完成后用free(msg);来释放

 

 

3.第二种方法有种不好的地方就是会浪费内存,对吧我们只需要16个字节,它一下给我分配了1024个,不像第一种方法那样想要多少分配多少。现在该变长数组登场了,

它结合了上面两种方法的优点,请看:

struct SMsg

{

      int msgid;

      unsigned int buffsize;

      char buff[0];

};

对你没有看错,数组的长度是0。然后你可以看看这个结构体的大小,在32位下是8,那个buff并没有占用内存。

我们怎么使用这个东西呢?现在我们同样是想使用大小为16的缓冲区。

SMsg *msg=(SMsg*)malloc(sizeof(SMsg)+16);

msg->buffsize=16;

可以直接使用msg->buff来对缓冲区进行操作。

使用完后,我们可以直接使用free(msg)来对其进行释放,是不是使用起来很方便。

 

为什么可以这样使用呢?我们来做个实验。

struct SChangeLenPack

{

      intbodySize;

      charbody[0];

};

struct Node

{

      intbodysize;

      char*data;

 };

 

int main()

{

      SChangeLenPackpack;

      printf("结构体的大小是:%d\n",sizeof(SChangeLenPack));

      printf("结构体开始地址:%p,数据包开始地址:%p:\n",&pack,&pack.body);

      printf("\n");

      Node  node;

      printf("结构体的大小是:%d\n",sizeof(Node));

      printf("结构体开始地址:%p,数据包开始地址:%p:\n",&node,node.data);

      return0;

}


可以看出变长数组的数据缓冲区,结构体最后一个成员之后继续来分配内存的。

而使用指针的那种方法,可以看出,指针指向的数据的内存是不连续的。所以不能只用free函数把所有的数据清除。

 

 

总结:


变长数组的优点:

变长结构体的内存是连续的,而使用指针的方法的不是,所以变长结构体只需释放一次空间,这样使用起来比较方便。

 

原创粉丝点击