如果我们假设这两个例子都出现在一个函数内部,那么在:
struct person p = {.name="apple"}
这个C语言实现会自动为p
分配内存,在函数执行结束时释放(或者,如果该语句在嵌套于该函数中的代码块中,则在该块执行结束时释放)。这对以下情况很有用:
- 你正在处理大小适中的对象。(对于大型对象,使用许多kibibytes的内存,使用
malloc
可能更好。阈值取决于具体情况。)
- 你一次只需处理少量对象。
在:
struct person* p_tr = malloc(sizeof(struct person))
p_tr->name = "apple"
程序显式请求对象的内存,通常应该在完成对象后使用 free 释放该内存。这在以下情况下很有用:
- 对象必须返回给函数调用方。自动对象在函数执行结束时将停止存在(在 C 的计算模型中;实际计算机内存并未停止存在,而是不再保留用于该对象),但是分配的对象将继续存在,直到程序释放它(或结束执行)。
- 对象非常大。(通常,C 实现提供更多的内存以供 malloc 分配,而不是为自动对象分配。)
- 程序将创建变量数量的此类对象,具体取决于某些情况,例如从输入创建链表、树或其他结构,其大小在读取之前不知道。
注意,struct person p = {.name="apple"}; 使用 "apple" 初始化了 name 成员,并将所有其他成员初始化为零。然而,使用 malloc 并将其分配给 p_tr->name 的代码未初始化其他成员。
如果 struct person p = {.name="apple"}; 出现在函数外部,则会创建具有静态存储持续时间的对象。它将存在于程序执行期间。
我们建议使用 struct person *p_tr = malloc(sizeof *p_tr); 而不是使用 struct person* p_tr = malloc(sizeof(struct person));。对于前者,仅更改 p_tr 类型的一个地方仍将请求正确的大小,而在使用后者时,更改 p_tr 需要在两个位置进行编辑,这会让人容易犯错。
sizeof(struct person)
orsizeof *p_tr
are valid, butsizeof(person)
is a syntax error. Best practice would be to usesizeof *p_tr
- William Pursellstruct person p = {.name="apple"};
创建的变量在封闭块结束时超出作用域(例如,如果这是在函数中,则内存在函数返回时变为无效)。而对于struct person *p
,变量p
在封闭作用域结束时也变得无效,但它所指向的数据仍然有效。 - William Pursell*ptr
存储在某个队列中,即使函数结束后尝试检索它,它仍将存在,但对于person p
不是这种情况吗? - Amandamalloc
,而第一个版本无法给你这种控制。 - M.M