- List item
零字节数组定义示例
typedef struct TWorkTwoTag TWorkTwo;
struct TWorkTwoTag
{
unsigned int p_one;
unsigned short p_two;
unsigned char p_count;
unsigned char p_home[0];
};
零字节数组使用示例
TWorkTwo *two = NULL;
two = (TWorkTwo*)malloc(17);
if (two != NULL)
{
two->p_one = 0;
two->p_two = 1;
two->p_count = 10;
memset(two->p_home, 0xFF, two->p_count);
unsigned char buff[32] = { 0 };
memcpy(buff, two, 17);
free(two);
}
含指针结构定义示例
typedef struct TWorkOneTag TWorkOne;
struct TWorkOneTag
{
unsigned int p_one;
unsigned short p_two;
unsigned char p_count;
unsigned char *p_stream;
};
含指针结构使用示例
TWorkOne one;
one.p_one = 0;
one.p_two = 1;
one.p_count = 10;
one.p_stream = (unsigned char*)malloc(one.p_count);
if (one.p_stream != NULL)
{
memset(one.p_stream, 0xFF, one.p_count);
unsigned char buff[32] = {0};
memcpy(buff, &one, sizeof(TWorkOne) -4);
memcpy(&buff[sizeof(TWorkOne)-4], one.p_stream, one.p_count);
free(one.p_stream);
}
差异说明
从上面两个结构的使用案例中看到,最后我们把这个变长结构拷贝到别的地方去时,零字节数据只需要拷贝一次,而带指针的结构需要分段拷贝。那是因为,零字节数据在整个结构动态内存分配后,数组地址上下是连续的,是从结构起始地址开始然后一直往下,分配的直接是内存地址;但是对于带指针的结构来说,内存分配的,是指针指向内存的地址(堆区),而结构的初始地址是在栈区分配的,两端地址自然不是连续的。而就算直接对结构进行动态内存分配,如下
TWorkOne *one;
one = (TWorkOne*)malloc(16);
if (one != NULL)
{
memset(one, 0xFF, 16);
free(one);
}
这里,对于指针来说,动态分配的是指针的地址,不是指针指向内存的地址,而通过memset 进行初始化后,其他几个变量都赋值了,而对于指针来说,对指针赋值就是将指针指向某块内存空间,这里就是指针指向了 0xFFFFFFFF 这块内存地址。
因此通过这种方式,无法对指针指向的内存进行动态分配(或者你可以再次对结构里面的指针进行动态分配)
468

被折叠的 条评论
为什么被折叠?



