当动态分配包含char指针的struct时,实际的char指针会发生什么?它存放在哪里?
一旦释放了struct,char指针是否随之释放?
例如,请考虑以下结构:
struct mix
{
int a;
float b;
char *s;
};
typedef struct mix mix;
然后是以下代码为它分配内存:
int main()
{
mix *ptr = (mix*)malloc(sizeof(mix));
ptr->a = 3;
ptr->b = 4.5f;
ptr->s = "Hi, there, I'm just a really long string.";
free(ptr);
return 0;
}
是否在堆栈上分配*s
,然后与*ptr
一起释放?我可以想象它确实是在堆栈上分配的,因为它不以任何方式动态分配(除非malloc具有一些我不知道的功能)。我认为*s
的“超出范围”将会解放*ptr
。或者我完全错了? :)
非常感谢!
答案 0 :(得分:6)
在调用char*
(其返回)后,s
成员mix
成员的空间与malloc()
的其他成员一起分配在堆上你不需要施放的价值)。分配给s
的字符串文字不在堆或堆栈上分配,而是实际二进制文件的一部分,并具有静态存储持续时间。所以这个:
ptr->s = "Hi, there, I'm just a really long string.";
将字符串文字的地址指定给ptr->s
。如果您希望ptr->s
指向字符串文字以外的内容,则需要malloc()
内存。对于每个malloc()
,必须有free()
,因此ptr->s
需要free()
d ptr
之前ptr->s
指向free()
仅动态分配内存。)
调用ptr
后,取消引用{{1}}是未定义的行为。
答案 1 :(得分:4)
当您使用mix
动态分配malloc()
时,实际上是在分配一块内存来存储mix
结构数据成员,即
int
(a
)float
(b
)char
(s
)当您致电free()
时,您只需发布 阻止。
因此,您不分配字符串,只需分配字符串指针。
如果要动态分配字符串,则必须显式执行(另一次调用malloc()
),并且为了避免内存泄漏,您还应该使用free()
显式释放字符串。< / p>
答案 2 :(得分:4)
当你使用malloc for ptr
时,会为结构的所有成员分配内存,包括指针s
,这与为结构的任何其他成员分配的内存没有区别。
您正在为s
分配一个字符串文字,所以它很好,通常存储在只读部分。否则,malloc
和ptr->s
也需要free
。因为,它是一个字符串文字,所以不需要在这里释放s
(这样做是UB)。
答案 3 :(得分:2)
mix* ptr
。 ptr指向的内容(mix类型的变量)在堆上动态分配,包括指针s
。
请注意s
没有指向任何内容,指针没有做任何有用的事情。你必须将它设置为指向可以在任何地方分配的东西。当你的结构被释放时,无论它指向什么都没有被释放。在这种情况下,您将其设置为指向ROM中分配的常量字符串文字,因此您无需担心这一点。
答案 4 :(得分:2)
是否在堆栈上分配了
*s
(即取消引用指针s
的结果)根本没有分配。在malloc
之后,ptr->s
是未初始化的指针。它没有指向任何内容,表达式*(ptr->s)
具有未定义的行为,直到您执行ptr->s = "Hi, etc"
。
一旦初始化ptr->s
指向字符串文字,*(ptr->s)
是字符串文字的第一个字符,因此它可能存在于可执行文件的某些数据部分中。除了结构的sizeof(mix)
字节之外,没有动态分配任何内容(在32位实现上可能是12个字节)。
答案 5 :(得分:2)
what happens with the actual char pointer? Where is it stored?
char *也像其他成员一样,占用一些字节(在64位机器中占用8个字节,类似于其他指针)。在您的情况下,您正在堆中为该结构实例分配内存。所以这个指针的内存也将被分配在为该结构实例分配的同一个堆中。
考虑这段代码。这给出了char *的位置:
#include <stdio.h>
typedef struct
{
int a;
float b;
char *s;
}mix;
int main()
{
printf("\n%d ,float:%d, int:%d, char*:%d", sizeof(mix), sizeof(float), sizeof(int), sizeof(char*));
return 0;
}
这个结构的大小是16个字节。由4字节整数,4字节浮点数和8字节char *组成。 (在64位操作系统中,如果操作系统是32位,则char *将为4个字节。)
And once the struct is freed, is the char pointer freed along with it?
通常不会释放char *指向的块(如果它指向malloc()分配的块)。只释放结构块。我们知道free()需要在分配期间为和平解除分配而返回的有效地址。如果你在没有释放char *的情况下自由,它将导致内存泄漏。
但是您的案例"Hi, there, I'm just a really long string.";
上面给出的字符串是字符串文字,它在程序的只读部分中分配。
使用gcc -S Yourprogram.c
这将生成.s文件。您可以查看此字符串的.read_only
部分。所以即使你删除你的结构实例,也不会有内存泄漏。因为您只是指向一个只读的地址。你不是为这个字符串分配内存。