【问题标题】:Allocating memory confusion in C在 C 中分配内存混淆
【发布时间】:2012-12-13 03:01:19
【问题描述】:

我已经环顾四周,但仍然无法理解它,假设我有结构:

struct some_struct {
    int x;
    int y;
    char *some_string;
};

假设我们有上面的结构,你会如何为上面的结构分配一些内存? 可以简单地做:

struct some_struct *test_struct;
test_struct = malloc(sizeof(struct some_struct));

但这足够了吗?您不需要为some_string 分配一些内存吗?或者如果结构体包含更多的指针,你是否也不需要为它们分配内存?

编辑:还有一件事……假设我的结构 some_struct 已经有数据,例如

struct some_struct *test_struct = malloc(sizeof(some_string);
test_struct->x = 2;
test_struct->y = 3;
test_struct->some_string = "sadlfkajsdflk";

以下代码是否足以释放分配的内存?

free(test_struct);

还是我也必须进去释放 char* some_string?

谢谢

【问题讨论】:

  • 关于编辑,你让test_struct->some_string指向一个字符串文字,而不是指向内存(m|c|re)alloced,所以在这种情况下你不应该free它。但是如果你有(m|c|re)alloced内存到test_struct->some_string,你应该在freeingtest_struct之前free它,否则你会泄漏内存。

标签: c memory struct malloc


【解决方案1】:

好的,这段代码没有做你想做的事:

struct some_struct *test_struct = malloc(sizeof(some_string);
test_struct->x = 2;
test_struct->y = 3;
test_struct->some_string = "sadlfkajsdflk";

在这种情况下,您的*test_struct 现在指向一个类型为some_sring 大小的“内存区域”(我认为您的 some_string 是char*)。

Malloc(X) 为您的程序(或进程)虚拟内存提供X 空间。 当你这样做时:

struct some_struct *test_struct; 

您有足够的空间来存储指向some_struct 的指针。

如果你这样做:

malloc(sizeof(struct some_struct));

您现在已经从虚拟内存中保留了struct some_struct 空间。但是您想知道该内存在“哪里”。这就是你将它分配给指针的原因:

test_struct = malloc (sizeof(struct some_struct));

[编辑]我会这样写:“为了让你的编译器更快乐,你还应该在其中包含一个演员表,告诉编译器 malloc 分配的空间将用于存储struct some_struct:”,给出紧随其后的一个例子。但事实上,事实并非如此。正如您在下面的 cmets 中看到的,@chutsu 纠正了这一点,为了说服自己,请检查此 question。 “主要”原因是您冒着很大风险去做这件事,根本没有任何好处。
其余代码现已更正:无强制转换。

一种更简洁的方法是对结构进行类型定义。然后,您的代码将如下所示:

typedef struct some_struct {
    int x;
    int y;
    char *some_string;
}SomeStruct;

SomeStruct *test_struct;
test_struct = malloc(sizeof(SomeStruct));

关于字符串分配。你可以这样想:用 malloc(及其兄弟 calloc、realloc...)创建的所有东西都需要释放! 发生这种情况是因为所有其他变量都是函数的局部变量,即使 main 也是一个函数,并且这些变量在函数终止时被清除。

因此,在分配结构后,如果您想要为字符串分配空间,则必须为其分配空间。

test_struct->some_string = malloc((YOUR_STRING_SIZE+SPACE_FOR_THE_STRING_TERMINATOR)*sizeof(char));

带有 - SPACE_FOR_THE_STRING_TERMINATOR=1\0 字符。

然后,如果你想释放test_struct,你必须先释放字符串,然后再释放结构,以相反的顺序,你会丢失指向字符串的指针并且会泄漏。 它看起来像这样:

free(test_struct->some_string);
free(test_struct);

就是这样,你已经完成了。

希望这会有所帮助。

【讨论】:

  • 实际上你并没有在 C 中的 malloc 前面加上一个演员表。看看我在这里写的一个帖子:chutsu.tumblr.com/post/38958361088/…
  • 我从该文档中得到的是,如果您忘记包含,您不应该投射?我通常会转换,因为我知道我希望它假设我知道它正在返回该类型。 EditNice tumblr 顺便说一句。
  • 不,相反,您不应该投射,因为您可能会忘记包含。诚然,链接的措辞很糟糕。但本质上,如果您使用 C 编译器进行强制转换,编译器会假定您知道自己在做什么。问题是,如果您忘记 #include <stdlib.h> 并且您在 malloc 前面有一个强制转换,编译器不会告诉您*您忘记包含 stdlib,而是给您其他无用的错误消息。检查此question :)
  • 啊!好的。实际上,这很有意义。你在这里学到的这种东西,事实上,非常棒!:) 我的老师从来没有提到过这样的东西,而且他们总是提到诸如“少写代码是避免错误的最好方法”之类的东西,并指出淘汰所有良好的编程实践。非常感谢@chutsu。必须编辑我的答案。
【解决方案2】:

调用malloc(sizeof(struct some_struct)); 为您的结构提供内存,其中包括两个整数字段和一个指针字段的空间。

但是,指针字段在指向内存中的有效位置之前不能使用。为此,您需要将其指向一个有效的内存位置,例如使用malloc 为其分配内存或将其指向预先存在的有效内存位置:

例如:

test_struct->some_string = malloc(100); // Allocate 100 bytes for the string

【讨论】:

  • 你好想知道你是否可以评论我新编辑的问题,谢谢:)
  • @chutsu,你用malloc 分配的任何东西都必须用free() 释放。因此,如果您使用malloctest_struct->some_string 分配内存,那么是的,您还必须使用free 释放它。但是在您的示例代码中,您只需将 test_struct 设置为字符串文字,这意味着您不需要释放它。
【解决方案3】:

运行这两行代码后:

struct some_struct *test_struct;
test_struct = malloc(sizeof(struct some_struct));

您已经完成了足够的工作,可以开始使用 test_struct。指针的值只是一个内存地址,因此malloc 为两个ints 和一个char* 分配了足够的空间。如果您想将test_struct->some_string 指向已经存在的char*,您可以这样做:

test_struct->some_string = some_other_char_pointer;

否则,您还需要为其分配内存:

test_struct->some_string = malloc(...);

【讨论】:

    【解决方案4】:

    您可能需要也可能不需要为字符串分配一些内存,具体取决于上下文。但是您提供的代码分配了保存该结构所需的所有内存。

    基本上,编写代码来完成您需要做的任何事情。字符串是否需要内存取决于您要做什么。

    仅使用您显示的代码,您分配的指针并不指向任何特定的东西,就像您分配的整数不包含任何特定的值一样。字符串的地址分配,如果需要,当您将some_string 的值设置为有用的值时,可能同时将xy 设置为有用的值。

    【讨论】:

      猜你喜欢
      • 2013-06-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多