#include <stdlib.h>
#include <string.h>
int main() {
struct string{
int len;
};
typedef struct string str;
char *s = "hello";
str *p = (str*)(malloc(sizeof(str) + strlen(s) + 1));//分配足够存下一个字符串的结构体
p->len = strlen(s);
memcpy(p + 1, s, strlen(s));//将字符串拷贝到紧邻结构体的内存处
}
- 这段程序的目标:将字符串拷贝到紧邻结构体的内存空间处,与结构体原有字段构成连续的内存空间(类似柔性数组的作用)。首先我们给它分配了sizeof(str) = 4 + strlen(s) = 2 + 1 = 7个字节,由于内存对齐的原因,需要补1个字节,所以声明的p结构体共占用8个字节,可以满足复制的需求。如图:
- 预期结果:如结构体的地址为0x602010,那么he字符串的位置应该在0x602010 + 0x4 = 0x602014位置上,占用2字节内存空间。
- 实际结果:该字符串却存到了0x602020位置上,与结构体起始地址0x602010相差了16个字节。通过gdb看到len字段的地址也是0x602010,sizeof(p->len)的值为4,说明len字段占用了0x602010 ~ 0x602014的地址,但是接下来这段0x602014 ~ 0x602020地址是没有任何值存储的(如下图),想问一下为什么会出现这种情况,谢谢。,
- 首先是一个很奇怪的现象,0x602010 + 0x4,打印出来的结果居然是:0x602020,为什么不是0x602014,而是0x602020呢?
- 先后打印结构体的值、字符串的值与地址、结构体len字段的地址、结构体的地址(与len字段地址相同),发现并不符合预期:
- 查看0x602014 ~ 0x602020处地址的值:
当p的类型为 str* 的时候,
p + 4
的值是p + 4*sizeof(str)
例:试试在gdb里p这几个值
剩下的你应该能自己推出来了