存储动态分配的结构中的字符数组在哪里?

时间:2012-10-18 09:19:20

标签: c struct dynamic-memory-allocation

  

可能重复:
  C Array Instantiation - Stack or Heap Allocation?

当动态分配包含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。或者我完全错了? :)

非常感谢!

6 个答案:

答案 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结构数据成员,即

  • inta
  • 一个floatb
  • 指针指向chars

当您致电free()时,您只需发布 阻止。

因此,您不分配字符串,只需分配字符串指针

如果要动态分配字符串,则必须显式执行(另一次调用malloc()),并且为了避免内存泄漏,您还应该使用free()显式释放字符串。< / p>

答案 2 :(得分:4)

当你使用malloc for ptr时,会为结构的所有成员分配内存,包括指针s,这与为结构的任何其他成员分配的内存没有区别。

您正在为s分配一个字符串文字,所以它很好,通常存储在只读部分。否则,mallocptr->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部分。所以即使你删除你的结构实例,也不会有内存泄漏。因为您只是指向一个只读的地址。你不是为这个字符串分配内存。