结构体定义:
//方法一:对结构体重命名 常用
typedef struct _Person{
int age;
char name[30];
int grade;
}Person;
//方法二:
struct Person{
int age;
char name[30];
int grade;
}p1,p2;
//方法三:
struct{
int age;
char name[30];
}p;
上面只是定义了一个数据类型,没有分配内存。对于结构体来说,是捆绑分配内存以及捆绑释放内存。即不用单独为每个成员分配内存,编译器直接给他们分配。
结构体捆绑分配内存:
在分配内存的时候注意字节对齐,也就是每个变量分配的内存应该是4(32位编译器)的倍数。
typedef struct _Person {
int age;
char c;
int grade;
char buf[5];
char * d;
}Person;
void main() {
Person p;
printf("p的地址:%d\n", &p);
printf("p.age :%d\n", &p.age);
printf("p.c :%d\n", &p.c);
printf("p.grade:%d\n", &p.grade);
printf("p.buf :%d\n", &p.buf);
printf("p.d :%d\n", &p.d);
}
p的地址和age的地址相同,虽然char c只占1个字节但是仍然分配了4个字节,这就是字节对齐,还有buf[5] 虽然占用5个字节但是分配了8个字节。这就是字节对齐。
结构体捆绑释放内存:
typedef struct _Teacher {
int age;
char a;
int grade;
char * p;
char name[20];
}Teacher;
void main() {
//初始化结构体
Teacher *t=(Teacher *)malloc(sizeof(Teacher));
t->age = 10;
t->a = 'a';
t->grade = 2;
t->p = (char *)malloc(100);
strcpy(t->p, "aaaaaaaaa");
strcpy(t->name, "1111111111");
printf("\n\n p的地址:%d\n", t->p);
printf(" name的地址:%d\n", t->name);
free(t);
printf("\n\n\n结束\n\n\n");
}

释放之前p指向内存空间内容,以及name内存空间的内容:

释放之后:
p所指向内存空间的内容不变,name内存空间中的内容发生改变。发生内存泄漏


所以结论是:
结构体在进行捆绑释放的时候,只会释放结构体内部的空间,比如age,a,grade,p,name的空间,因为这些都在结构体的内部,而p所指向的内存空间在结构体的外部,不会进行释放。
所以我们在进行结构体释放的时候,一定要从内向外释放。
free(t->p);
t->p=NULL;//个人为人不用进行这一步,因为下一步,即将把p的内存释放掉
free(t);
t=NULL;//这一步很有必要,避免产生野指针。

本文探讨了C语言中结构体的定义、内存分配与释放,特别是字节对齐的原则。在结构体捆绑分配内存时,编译器会遵循字节对齐规则,如为char分配4个字节,为buf分配8个字节。结构体捆绑释放内存时,只会释放结构体内部空间,不会释放成员变量p所指向的外部内存,因此需要额外手动释放,以防止内存泄漏。在释放结构体后,确保将指针设为NULL以避免野指针问题。
1905

被折叠的 条评论
为什么被折叠?



