Seb*_*Seb 5 c memory malloc struct memory-management
我试图理解C中的结构的内存分配,但我坚持下去.
struct Person {
char *name;
int age;
int height;
int weight;
};
struct Person *Person_create(char *name, int age, int height, int weight)
{
struct Person *who = malloc(sizeof(struct Person));
assert(who != NULL);
who->age = age;
who->height = height;
who->weight = weight;
who->name = strdup(name);
return who;
}
int main(int argc, char *argv[])
{
struct Person *joe = Person_create("ABC", 10, 170, 60);
printf("Size of joe: %d\n", sizeof(*joe));
printf("1. Address of joe \t= %x\n", joe);
printf("2. Address of Age \t= %x\n", &joe->age);
printf("3. Address of Height \t= %x\n", &joe->height);
printf("4. Address of Weight \t= %x\n", &joe->weight);
printf("5. Address of name \t= %x\n", joe->name);
...
Run Code Online (Sandbox Code Playgroud)
我不明白的是这个结构的内存分配.在我的打印输出上,我看到了这个:
Size of joe: 24
1. Address of joe = 602010
2. Address of Age = 602018
3. Address of Height = 60201c
4. Address of Weight = 602020
5. Address of name = 602030
Run Code Online (Sandbox Code Playgroud)
问题:
*name计算名称的大小仅指向第一个字符?对象joe的地址与数据成员的地址之间没有间隙age.此范围由数据成员占用 name.
struct Person {
char *name;
int age;
//...
Run Code Online (Sandbox Code Playgroud)
根据输出
1. Address of joe = 602010
2. Address of Age = 602018
Run Code Online (Sandbox Code Playgroud)
它占用平台中的8个字节sizeof( char * )等于8.它的地址与对象joe本身的地址一致.
在这个声明中
printf("5. Address of name \t= %x\n", joe->name);
Run Code Online (Sandbox Code Playgroud)
你没有输出name自己的地址.您打印了存储在此指针中的值,该值是"ABC"通过使用获得的字符串文字副本的第一个字符的地址 strdup.
因此,输出4和5中的值之间存在差距,因为它们是不同的存储器范围.数据成员weight属于对象,joe而字符串文字的副本"ABC"存储在对象外部.该对象只有数据成员name,指向文字副本的第一个字符.
作为name一个指针然后它的大小计算如下
sizeof( char * )
Run Code Online (Sandbox Code Playgroud)
要么
sizeof( joe->name )
Run Code Online (Sandbox Code Playgroud)
如我在帖子开头所解释的那样等于8.
如果要确定字符串文字的长度,则应使用标strlen头中声明的标准函数<string.h>.例如
printf( "%zu\n", strlen( joe->name ) );
Run Code Online (Sandbox Code Playgroud)
为什么1和2之间存在差距?
struct的起始地址始终等于它的第一个成员的地址.从C标准:
6.7.2.1-13.指向适当转换的结构对象的指针指向其初始成员
第一个成员不是age,但是name.所以以下两行应该打印相同的地址:
printf("1. Address of joe \t= %x\n", joe);
printf("1. Address of name-pointer \t= %x\n", &joe->name);
Run Code Online (Sandbox Code Playgroud)
在你的代码中,
printf("5. Address of name \t= %x\n", joe->name);
Run Code Online (Sandbox Code Playgroud)
不打印指针的地址,而是指针指向的数据的地址.
如何计算*name的大小,因为名称仅指向第一个char?
name是一个指针,它占用8个字节的内存,无论它指向的数据大小如何(可能是一个字符串,如你的情况,一个char,一个int或其他).
为什么4和5之间存在差距?
用于存储实际name字符串的内存不在struct中 - 在某处strdup分配内存以将字符串复制到其中.这恰好是结构的最后一个成员之后的16个字节.然后指针指向此内存位置.name
请注意,填充和内存对齐只是结构大小的一个因素(它们与您明确陈述的问题无关).由于struct包含一个指针(在您的机器上为8个字节)和3个整数(每个4个字节),因此可以假设总大小为20个字节.在大多数平台上,内存是8字节对齐的 - 这就是为什么结构的大小向上舍入到24字节的原因.这样,如果声明一个Persons 数组,则每个数组元素从一个8字节对齐的地址开始,即地址值可以均匀地除以8.
这是由于所谓的数据对齐。引用自本网站
C/C++ 中的每种数据类型都会有对齐要求(实际上它是由处理器架构而不是语言强制要求的)。
然后将这一要求扩展到结构:
由于各种数据类型的对齐要求,结构体的每个成员都应该自然对齐。
您可以通过这篇文章进行详细阅读。
| 归档时间: |
|
| 查看次数: |
1282 次 |
| 最近记录: |