结构体中有指针,为其分配内存

vernal 2009-07-09 11:03:33
typedef struct s1
{
unsigned int Length;
unsigned char* Data;
}S1;

typedef struct mystruct
{
unsigned char Header;
unsigned char* Body;
S1 ss1;
}MY_STRUCT,*MY_STRUCT_PTR;




char data[3000]; //里面已经预填充了相关数据
MY_STRUCT_PTR my_struct1=new MY_STRUCT;


现在我需要将data中的内容,按照一定顺序拷贝到my_struct1里(先拷贝Header,ss1,剩下的都是给Body),并且最重要一点,my_struct1的内存分配,必须保证
body是紧接着ss1的。

...全文
493 17 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
fengqunying71 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dream19861009 的回复:]
先拷贝Header :先从 data 取一个 char  放进去,从data[0]开始取
再拷贝ss1:实际上sizeof(S1)也就是2*sizeof(int) 再从data中取 8*sizeof(char),从data[1]开始取
最后body:你所说的“剩下的都是给Body” 是不是指 找到“紧接着ss1的”的地址 赋给 my_struct1->Body 就可以了 ,那应该就是
my_struct1->Body = (unsigned char*)(&data[9]);

[/Quote]
不好意思,上面是搞错引用啦。。。
好像不能这样。。

终于搞懂struct结构体内存分配问题了,结构体中各个成员字节对齐遵循以下几个原则:
1.结构体每个成员相对于结构体首地址的偏移量(offset)都是(这个)成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
例如有以下一个结构体
struct ex {
int i;
char t;
int n;
}
第1个成员偏移量为0,是int型成员大小4(假设这太机器的整型长度占4个字节)的整数倍。
第2个成员 t 为char型,他的大小为1,首先假设在成员i和t之间没有填充字节,由于i是整型,占4个字节那么在没有填充之前,第2个成员t相对于结构体的偏移量为4,他是t成员大小1的4倍,符合此条件,所以系统在给结构体第2个成员分配内存时,不会在i和t之间填充字节以到达对齐的目的。
当分配结构体第3个成员n时,首先发现是一个整型数据,大小为4,没有填充之前,n相对于结构体首地址偏移量为:前面2个成员+填充字节=5,所以当系统发现5不是4(成员大小)的整数倍时,会在成员t之后(或者说n之前)填充3个字节,以使n的偏移量到达8而成为4的整数倍。这样这个结构体占用内存情况暂时为4+1+3+4。
2.结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
上面的结构体内存分配以后还要看是否满足此条件,假设在最末一个成员之后不需填充字节数,那么这个结构体的大小为12。而ex结构体中最宽基本类型成员为int,大小为4,12为4的整数倍,所以无须再在最末一个成员之后加上填充字节了。所以sizeof(ex)=12;
如果一个结构体如下所示struct ex1{
int i;
char t;
int n;
char add;
}
那么sizeof(ex1) =16;原因就是在最后一个成员之后填充了3个字节。
3.还有一个额外的条件:结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

O(∩_∩)O~ 慢慢看哦··
data【9】好像不是4的整数倍···所以系统会自动填充字节数 故不能紧连着S1对body进行存储
fengqunying71 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 beyond071 的回复:]
s1中的Data和mystruct中的Body都用new分配内存,再写个析构函数释放好了。
如果说内存上一定要相邻,那就分配一块内存,自行划分也可以。
[/Quote]
好像不能这样。。

终于搞懂struct结构体内存分配问题了,结构体中各个成员字节对齐遵循以下几个原则:
1.结构体每个成员相对于结构体首地址的偏移量(offset)都是(这个)成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
例如有以下一个结构体
struct ex {
int i;
char t;
int n;
}
第1个成员偏移量为0,是int型成员大小4(假设这太机器的整型长度占4个字节)的整数倍。
第2个成员 t 为char型,他的大小为1,首先假设在成员i和t之间没有填充字节,由于i是整型,占4个字节那么在没有填充之前,第2个成员t相对于结构体的偏移量为4,他是t成员大小1的4倍,符合此条件,所以系统在给结构体第2个成员分配内存时,不会在i和t之间填充字节以到达对齐的目的。
当分配结构体第3个成员n时,首先发现是一个整型数据,大小为4,没有填充之前,n相对于结构体首地址偏移量为:前面2个成员+填充字节=5,所以当系统发现5不是4(成员大小)的整数倍时,会在成员t之后(或者说n之前)填充3个字节,以使n的偏移量到达8而成为4的整数倍。这样这个结构体占用内存情况暂时为4+1+3+4。
2.结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
上面的结构体内存分配以后还要看是否满足此条件,假设在最末一个成员之后不需填充字节数,那么这个结构体的大小为12。而ex结构体中最宽基本类型成员为int,大小为4,12为4的整数倍,所以无须再在最末一个成员之后加上填充字节了。所以sizeof(ex)=12;
如果一个结构体如下所示struct ex1{
int i;
char t;
int n;
char add;
}
那么sizeof(ex1) =16;原因就是在最后一个成员之后填充了3个字节。
3.还有一个额外的条件:结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

[color=#FF0000]O(∩_∩)O~ 慢慢看哦··
data【9】好像不是4的整数倍···所以系统会自动填充字节数 故不能紧连着S1对body进行存储[/color]
fengqunying71 2009-12-15
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dream19861009 的回复:]
先拷贝Header :先从 data 取一个 char  放进去,从data[0]开始取
再拷贝ss1:实际上sizeof(S1)也就是2*sizeof(int) 再从data中取 8*sizeof(char),从data[1]开始取
最后body:你所说的“剩下的都是给Body” 是不是指 找到“紧接着ss1的”的地址 赋给 my_struct1->Body 就可以了 ,那应该就是
my_struct1->Body = (unsigned char*)(&data[9]);

[/Quote]
拷贝ss1:实际上sizeof(S1)也就是2*sizeof(int)
为什么?S1里的int lenght是占四个字节 难道char data也占四个字节??
vernal 2009-07-09
  • 打赏
  • 举报
回复
搞定。。。。。。。。。。

谢谢各位
大前置 2009-07-09
  • 打赏
  • 举报
回复
remalloc可以保证数据紧挨
Walf_ghoul 2009-07-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 asksgp 的回复:]
不会,等星星来解答。
[/Quote]
....
pengzhixi 2009-07-09
  • 打赏
  • 举报
回复
MY_STRUCT_PTR my_struct1=new MY_STRUCT; //动态分配一个MY_STRUCT对象


my_struct1->Body=new char[n];//为my_struct1所指对象的成员Body分配内存

(my_struct1->ss1).Data=new unsigned char[n]//为my_struct1所指对象的ss1成员里面的data分配内存
stormxs 2009-07-09
  • 打赏
  • 举报
回复
学习了
vernal 2009-07-09
  • 打赏
  • 举报
回复
不是的,my_struct1的内存分配,必须保证body是紧接着ss1的。
你那样是简单的吧指针指向char【9】而已啊,my_struct1->Body 在内存中的地址,并没有和my_struct1->ss1是紧挨着吧?
dream19861009 2009-07-09
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 vernal 的回复:]
引用 2 楼 dream19861009 的回复:
先拷贝Header :先从 data 取一个 char 放进去,从data[0]开始取
再拷贝ss1:实际上sizeof(S1)也就是2*sizeof(int) 再从data中取 8*sizeof(char),从data[1]开始取
最后body:你所说的“剩下的都是给Body” 是不是指 找到“紧接着ss1的”的地址 赋给 my_struct1->Body 就可以了 ,那应该就是
my_struct1->Body = (unsigned char*)(&data[9]);




my_struct1->Body = (unsigned char…
[/Quote]


ss1占用8个字节空间 body就是1009开始的啊
vernal 2009-07-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 dream19861009 的回复:]
先拷贝Header :先从 data 取一个 char 放进去,从data[0]开始取
再拷贝ss1:实际上sizeof(S1)也就是2*sizeof(int) 再从data中取 8*sizeof(char),从data[1]开始取
最后body:你所说的“剩下的都是给Body” 是不是指 找到“紧接着ss1的”的地址 赋给 my_struct1->Body 就可以了 ,那应该就是
my_struct1->Body = (unsigned char*)(&data[9]);
[/Quote]


my_struct1->Body = (unsigned char*)(&data[9]);

这样得到的是data[9]的地址吧,而不是ss1接下来的地址。
假设程序中:Header占用1字节空间,地址是1000;ss1咱用4字节空间,其实地址是1001,结束地址是1004;那么body的地址我要求是1005开始,占用了剩下的2995个空间。
beyond071 2009-07-09
  • 打赏
  • 举报
回复
s1中的Data和mystruct中的Body都用new分配内存,再写个析构函数释放好了。
如果说内存上一定要相邻,那就分配一块内存,自行划分也可以。
大前置 2009-07-09
  • 打赏
  • 举报
回复
//len为长度, ch为header
my_struct1.Header = ch;
my_struct1.ss1.Length = len;
my_struct1.ss1->Data = (char*)malloc(my_struct1.ss1.Length);
memcpy(my_struct1.ss1->Data, data, my_struct1.ss1->Data);

//length 为Body数据长度
my_struct1.ss1->Data = (unsigned char *)remalloc(my_struct1.ss1.Length+length);
memcpy(my_struct1.Body+my_struct1.ss1.Length, data, length);
dream19861009 2009-07-09
  • 打赏
  • 举报
回复
先拷贝Header :先从 data 取一个 char 放进去,从data[0]开始取
再拷贝ss1:实际上sizeof(S1)也就是2*sizeof(int) 再从data中取 8*sizeof(char),从data[1]开始取
最后body:你所说的“剩下的都是给Body” 是不是指 找到“紧接着ss1的”的地址 赋给 my_struct1->Body 就可以了 ,那应该就是
my_struct1->Body = (unsigned char*)(&data[9]);
asksgp 2009-07-09
  • 打赏
  • 举报
回复
不会,等星星来解答。
dskit 2009-07-09
  • 打赏
  • 举报
回复
typedef struct mystruct
{
unsigned char Header;
unsigned char* Body;
S1 ss1;
}MY_STRUCT,*MY_STRUCT_PTR;

-->

typedef struct mystruct
{
unsigned char Header;
S1 ss1;
unsigned char* Body;
}MY_STRUCT,*MY_STRUCT_PTR;

memcpy(my_struct1, data, sizeof(mystruct) - sizeof(char *));
my_struct1->Boby = (unsigned char*)(data + sizeof(mystruct) - sizeof(char *));
fiaifi 2009-07-09
  • 打赏
  • 举报
回复
直接一次性的把所有空间分配好(char数组),然后再根据需求把相应的地址赋给对应的指针就可以啦。令my_struct1指向这个char数组首地址。然后[首地址+16]的值赋给Body指针(header会占4字节),这样就可以了。
我唯一不明白的地方是S1中的Data指针要存放什么?

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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