mlloc()动态分配带指针的结构体内存,牛人看过来

96掌门师兄 2011-09-29 04:22:47
放假前,牛人们来看看这个结构体怎么malloc内存,我选择1个字节对齐的

//心跳包结构,大小为20
typedef struct tagTHeartBeat
{
int type; //心跳类型
time_t lastSendTime;
time_t lastRecvTime;
int recvInterval;
int sendInterval;
}THeartBeat, *pHeartBeat;


//消息体结构, 大小为12
typedef struct tagTSocketMsg
{
tagTSocketMsg()
{
m_msg = NULL;
}
int msgType; //消息类型
int msgLen; //消息体长度
char *m_msg; //消息体,可以指向任意长度,这里希望存放心跳包,等会强转
}TSocketMsg, *pSocketMsg;

//因为这里存放心跳包,所以pMsg大小就是消息
1. TSocketMsg *pMsg = (TSocketMsg*)malloc(sizeof(TSocketMsg)+ sizeof(THeartBeat) - 4); //要减指针 m_msg长度吗

2. m_msg可以带不定长度的消息,我该如何为TSocketMsg的变量 动态分配内存呢? 如果我用send(, pMsg, XX)这里的长度该如何填呢?

3. TSocketMsg *pMsg = (TSocketMsg*)malloc(sizeof(TSocketMsg)+ sizeof(THeartBeat));
cout << sizeof(*pMsg) << endl; //为什么这里还是12,sizeof求出来的不是实际内存的大小吗? 这里*pMsg大小是多少呢?
如果TSocketMsg *pMsg = (TSocketMsg*)malloc(200);那么实际分配的大小应该是200吧?超出的部分怎么分配呢?



...全文
292 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
sharptiger123 2011-10-09
  • 打赏
  • 举报
回复
字节对齐
JsenLong 2011-10-08
  • 打赏
  • 举报
回复
char *m_msg 这样写错了吧,就应该是char buf[];
cout << sizeof(*pMsg) << endl;为12是对的,两个int 等于8+ char* = 12
横云断岭 2011-10-08
  • 打赏
  • 举报
回复
从内存布局来看,
tagTSocketMsg的内存是
4 + 4 + 4

LZ贴出的代码里用了些技巧。
TSocketMsg *pMsg = (TSocketMsg*)malloc(sizeof(TSocketMsg)+ sizeof(THeartBeat) - 4);
实际上内存是这样用的:
4 + 4 + sizeof(THeartBeat)

这样可以节省4个字节的内存,也可以减少一次内存分配。
因为THeartBeat的大小确定,而且比较小。实际上,如果是只有THeartBeat消息包,完全可以这样定义:

typedef struct tagTSocketMsg
{

int msgType; //消息类型
int msgLen; //消息体长度
THeartBeat msgHeartBeat; //心跳包
}TSocketMsg, *pSocketMsg;

如果不这样做,代码应该是这样的。
TSocketMsg *pMsg = (TSocketMsg*)malloc(sizeof(TSocketMsg);
pMsg->m_msg = (THeartBeat*)malloc(sizeof(THeartBeat));

这样做还有一个好处,就是发送这个包时,直接发送就行了,不用组包。
所以:
如果我用send(, pMsg, XX)这里的长度该如何填呢?
XX = (sizeof(TSocketMsg)+ sizeof(THeartBeat) - 4

cout << sizeof(*pMsg) << endl; //为什么这里还是12,sizeof求出来的不是实际内存的大小吗

sizeof是编译时期就确定了。据内存布局决定结构体的大小。

如果TSocketMsg *pMsg = (TSocketMsg*)malloc(200);那么实际分配的大小应该是200吧?超出的部分怎么分配呢?

malloc只负责返回一块未使用的内存,至于这块内存是什么格式,你怎么用,完全是自个的事。


healer_kx 2011-10-08
  • 打赏
  • 举报
回复
看来不好说清楚了。
横云断岭 2011-10-08
  • 打赏
  • 举报
回复
LZ果真是一年经验,7K+薪水?
这个实际是是一个网络传输包。
一个包的内容是:
长度 + 类型 + 消息的具体内容

只有这样定义了包的格式,另外一端才能正确解包处理。
ndy_w 2011-09-30
  • 打赏
  • 举报
回复
显然指针是不应该在网络上传输的。一般不应该在网络上直接传输一个结构指针指向的连续内存。通信协议应该是描述每个字节,每个位是什么含义。如果你是在准备报文,那么应该先确定协议;分配可复用的BYTE*类型的缓冲区,并有工具把结构描述的内容变成报文,或反过来。
ndy_w 2011-09-29
  • 打赏
  • 举报
回复
1 -4什么意思?如果不-4,我猜你是想把两个结构在内存中连续存放。可是-4后就存不下了。
2 TSocketMsg的大小不变的,无论msg长度如何,这个结构只存储一个指针。
3 sizeof(*pMsg)就是TSocketMsg的大小,包括2个int和1个指针=12字节。
一条晚起的虫 2011-09-29
  • 打赏
  • 举报
回复
// sizeof(*pMsg)是结构的长度,不包括 pMsg->m_msg对应的字符串的长度。
// 对于 pMsg->m_msg,要单独分配内存。
WaistCoat08 2011-09-29
  • 打赏
  • 举报
回复
你发包时,要char *m_msg;的内容发到Buffer里。
也就是:
tagTHeartBeat + tagTSocketMsg(不包括char* msg) + 数据(char* msg指向的内容)
oyljerry 2011-09-29
  • 打赏
  • 举报
回复
sizeof 求的是结构体对象大小,里面只有指针,不会包含指针指向的空间
WaistCoat08 2011-09-29
  • 打赏
  • 举报
回复
首先弄清指针的概念。

传输时数据里是没有指针的概念的,就是一块数据Buffer

16,550

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Creator Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧