TLV@C

来源:互联网 发布:我欲封天灵宠进阶数据 编辑:程序博客网 时间:2024/04/26 08:13

 void arg_test(int i, ...);

int main()
{
 int int_size = _INTSIZEOF(int);
 printf("int_size=%d\n", int_size);
 arg_test(0,4);

 arg_cnt(4,1,2,3,4);
 return 0;
}

void arg_test(int i, ...)
{
 int j=0;
 va_list arg_ptr;//不定参数指针?

 va_start(arg_ptr, i);//start from i

 return;
 
}

/**************************************************************************/
//一个TLV结构的例子
struct pppoe_tag{
    __u16 type;
 __u16 len;
 char data[0];
}TLV_STRU;

//最后一个成员data为可变长数组,创建时,malloc一段结构体大小加上可变长
//数据的长度的空间给他,可变长部分按数组的方式访问,释放时,直接把整个
//结构体free就可以了。
void main()
{
 struct TLV_STRU *pstTlv;
 __u16 usTlvLen = 10;//数组10个元素

 //malloc
 pstTlv = (TLV_STRU*)malloc(sizeof(TLV_STRU) + sizeof(char)*usTlvLen);

 //set value
 pstTlv->type = 0xffff;
 pstTlv->len = usTlvLen;//注意这里是数据区的长度
 pstTlv->data[0]=...;
 pstTlv->data[1]=...;
 ...;

 

 //free
 free(pstTlv);
 return;
}

/*
这里的char data[0]是否可以用char *data来代替呢?
其实两者是有很大的差别的,为了说明问题,参照以下程序
*/

struct tag1
{
 int a;
 int b;
};

struct tag2
{
 int a;
 int b;
 char *c;
}

struct tag3
{
 int a;
 int b;
 char c[0];
}

struct tag4
{
 int a;
 int b;
 char c[1];
}

int main()
{
 struct tag2 l_tag2;
 struct tag3 l_tag3;
 struct tag4 l_tag4;

 memset(&l_tag2, 0, sizeof(struct tag2));
 memset(&l_tag3, 0, sizeof(struct tag3));
 memset(&l_tag4, 0, sizeof(struct tag4));

 printf("size of tag1 = %d\n", sizeof(struct tag1)); //4+4=8包含两个32位的整数,占用8字节空间  1个字节=8位
 printf("size of tag2 = %d\n", sizeof(struct tag2)); //12 指针占用4个字节
 printf("size of tag3 = %d\n", sizeof(struct tag3)); //8
 printf("size of tag4 = %d\n", sizeof(struct tag4)); //9

 printf("l_tag2=%p, &l_tag2.c=%p, l_tag2.c=%p\n", &l_tag2, &l_tag2.c, l_tag2.c);
 //out: l_tag2 = 0xbffffad0,&l_tag2.c = 0xbffffad8,l_tag2.c = (nil)
 printf("l_tag3=%p, l_tag3.c=%p\n", &l_tag3, l_tag3.c);
 //out: l_tag3 = 0xbffffac8,l_tag3.c = 0xbffffad0--c的值,就是c的首地址!!!
 printf("l_tag4=%p, l_tag4.c=%p\n", &l_tag4, l_tag4.c);
 //out:  l_tag4 = 0xbffffabc,l_tag4.c = 0xbffffac4--同上

 exit(0);
}


/*
如果用char*,像上面tag2,除了会占用多4个字节的指针变量外,用起来也很不方便
方法一:创建时,需要对结构体分配一块内存,再为指针分配内存,这样释放时,要首先
释放指针占用的内存,在释放结构体占用的内存,不方便
方法二:创建时,直接为结构体分配一块结构体大小加上指针指向的大小的内存,
并且要对结构体的内容进行初始化,让指针指向结构体后面的内存,即分配给他的内存
如下:
*/
struct tlv_tag{
 __u16 type;
 __u16 len;
 char *data;
}TLV2_STRU;

TLV2_STRU *pstTlv2;
__u16 tlvLen = 10;

//method1
pstTlv2 = (TLV2_STRU*)malloc(sizeof(TLV2_STRU));
pstTlv2->len = tlvLen;//注意len是什么含义
pstTlv2->data = malloc(sizeof(char)*tlvLen);
pstTlv2->data[0]=...;
...;

free(pstTlv2->data);
free(pstTlv2);

//method2
pstTlv2 = (TLV2_STRU*)malloc(sizeof(TLV2_STRU) + sizeof(char)*tlvLen);
pstTlv2->len = tlvLen;//注意len是什么含义
pstTlv2->data = (char*)pstTlv2 + sizeof(TLV2_STRU);//这里有问题吧???
pstTlv2->data[0]=...;
...;

free(pstTlv2);
/*
可见,不管使用哪种方法,都不如直接定义char data[0]来得方便,需要说明的是,
最后一个成员变量的定义为char data[0],某些编译器不支持长度为0的数组的定义,
在这种情况下,只能将它定义为char data[1],使用方法相同 !
*/

原创粉丝点击