ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

如何定义一个自带数据区的结构体:三种数据结构体的比较

2021-07-22 15:33:51  阅读:174  来源: 互联网

标签:pDN2 address char 三种 printf 自带 数据结构 DATA 0x%


先看如下三个结构体的定义

这三个结构体的前三个成员都相同,前两个成员只是为了充个数,从而让我们定义的struct看上去真的像个结构体,一个是char类型,一个是int类型。最后一个也是int类型,iDataLen用于记录结构体自带数据的长度,pData指向的就是我们“认为”的数据区。

// 结构体1
typedef struct data_node1{
	char	cDummy;			
	int	iDummy;
	int	iDataLen;
	char*	pData;
}DATA_NODE1;
// 结构体2
typedef struct data_node2{
	char	cDummy;
	int	iDummy;
	int	iDataLen;
	char	pData[1];
}DATA_NODE2;
// 结构体3
typedef struct data_node3{
	char	cDummy;
	int	iDummy;
	int	iDataLen;
	char*	data(){
		return (char*)(this+1);
	}
}DATA_NODE3;

再写代码打印三个数据结构的信息

首先显示结构体的大小,前两个结构体是16字节,最后一个结构体是12字节,这个好理解,最后一个结构体中缺少一个成员变量。
说明一下:cDummy虽然是一个char类型,但由于结构体按照最大成员变量的size进行对齐,即使cDummy只需要个单室套,但计算机还是给它分了个三居室。
打个比方:如果你和吴亦凡在同一个struct中,那么你的size也会和“吴签”对齐的,计算机的世界就是这么平等。
在该函数中我们开辟三个256字节的内存块,并让其分别指向三个结构体,从而观察pData到底指向哪里。

#define INT_DATA_SIZE	256
void TestStruct()
{
	// 获取结构体的大小
	int iDNSize1 = sizeof(DATA_NODE1);
	int iDNSize2 = sizeof(DATA_NODE2);
	int iDNSize3 = sizeof(DATA_NODE3);

	printf("sizeof(DATA_NODE1) = %d\r\n", iDNSize1);
	printf("sizeof(DATA_NODE2) = %d\r\n", iDNSize2);
	printf("sizeof(DATA_NODE3) = %d\r\n", iDNSize3);

	// 分配三块内存,并初始化为0
	char* pData1 = (char*)malloc(INT_DATA_SIZE);
	memset(pData1, 0, INT_DATA_SIZE);
	char* pData2 = (char*)malloc(INT_DATA_SIZE);
	memset(pData2, 0, INT_DATA_SIZE);
	char* pData3 = (char*)malloc(INT_DATA_SIZE);
	memset(pData3, 0, INT_DATA_SIZE);

	// 将三块内存指向对应的结构体
	DATA_NODE1* pDN1 = (DATA_NODE1*)pData1;
	DATA_NODE2* pDN2 = (DATA_NODE2*)pData2;
	DATA_NODE3* pDN3 = (DATA_NODE3*)pData3;

	// 打印结构体1的数据
	
	printf("DATA_NODE1       : address = 0x%08x\r\n", pDN1);
	printf("  pDN1->cDummy   : address = 0x%08x, value = %d\r\n", &pDN1->cDummy, pDN1->cDummy);
	printf("  pDN1->iDummy   : address = 0x%08x, value = %d\r\n", &pDN1->iDummy, pDN1->iDummy); 
	printf("  pDN1->iDataLen : address = 0x%08x, value = %d\r\n", &pDN1->iDataLen, pDN1->iDataLen);
	printf("  pDN1->pData    : address = 0x%08x, poiter address = 0x%08x\r\n\r\n", &(pDN1->pData), pDN1->pData);
		

	// 打印结构体2的数据
	int iSizeStruct2 = pDN2->pData - (char*)pDN2;
	pDN2->iDataLen = INT_DATA_SIZE - iSizeStruct2;
	printf("DATA_NODE2       : address = 0x%08x\r\n", pDN2);
	printf("  pDN2->cDummy   : address = 0x%08x, value = %d\r\n", &pDN2->cDummy, pDN2->cDummy);
	printf("  pDN2->iDummy   : address = 0x%08x, value = %d\r\n", &pDN2->iDummy, pDN2->iDummy); 
	printf("  pDN2->iDataLen : address = 0x%08x, value = %d\r\n", &pDN2->iDataLen, pDN2->iDataLen);
	printf("  pDN2->pData    : address = 0x%08x, poiter address = 0x%08x\r\n\r\n", &(pDN2->pData), pDN2->pData);

	// 打印结构体3的数据
	int iSizeStruct3 = pDN3->data() - (char*)pDN3;
	pDN3->iDataLen = INT_DATA_SIZE - iSizeStruct3;
	printf("DATA_NODE3       : address = 0x%0x\r\n", pDN3);
	printf("  pDN3->cDummy   : address = 0x%0x, value = %d\r\n", &pDN3->cDummy, pDN3->cDummy);
	printf("  pDN3->iDummy   : address = 0x%0x, value = %d\r\n", &pDN3->iDummy, pDN3->iDummy); 
	printf("  pDN3->iDataLen : address = 0x%0x, value = %d\r\n", &pDN3->iDataLen, pDN3->iDataLen);
	printf("  pDN3->data()   : address = 0x%0x\r\n\r\n", pDN3->data());

	free(pData1);
	free(pData2);
	free(pData3);

}

运行结果如图:

在这里插入图片描述

最后看三个结构体在内存中的显示

为了直观表达结构体的内存,我们假设三个结构体初始地址均为0x10000000。

结构体1
结构体1
结构体2
在这里插入图片描述
结构体3
在这里插入图片描述

显然,后两种方式可以实现数据区与结构体有机的结合在一起。那么这种定义的应用场景在哪呢?就举一个IP数据报文的例子吧。
在这里插入图片描述

标签:pDN2,address,char,三种,printf,自带,数据结构,DATA,0x%
来源: https://www.cnblogs.com/softlee/p/15044328.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有