在堆中使用指定的初始化器
Posted
技术标签:
【中文标题】在堆中使用指定的初始化器【英文标题】:Using Designated Initializers with the Heap 【发布时间】:2016-05-27 23:13:53 【问题描述】:可以毫无问题地使用designated initializers
,如下所示(对于“billy”),但是当在动态内存上使用相同的初始化方法时,编译时会出现问题。
使用指定初始化器有什么限制?
除了我们正在写入的where(即地址)之外,是什么让这两个初始化不同?为什么我们不能在动态内存中使用指定的初始化器?
struct student
char *name;
int age;
;
void print_student(struct student* st)
printf("Student: %s is %d years old\n", st->name, st->age);
int main(void)
srand(time(NULL));
struct student *molly_ptr = malloc(sizeof(struct student));
struct student billy =
.name = "billy",
.age = rand()%30
;
*molly_ptr =
.name = "molly",
.age = 25
;
//molly_ptr->name = "molly";
//molly_ptr->age = 25;
print_student(&billy);
print_student(molly_ptr);
return 0;
error: expected expression before '' token
*molly_ptr =
^
【问题讨论】:
初始化和赋值是两个不同的东西。您尝试做的第二件事是分配。该语法不适用于那些 AFAIK。 (与堆/堆栈无关。)char *name
最好声明为const char *name
。
@Lundin,代码仅针对这个问题生成。从技术上讲,还有内存泄漏。
@Lundin:但从技术上讲,实际上并非如此。每个资源都在main
退出之前释放,您的操作系统也带有内存管理系统,它会在您的进程退出后释放所有内存。例如,Git 根本不会释放任何资源。
【参考方案1】:
你必须写:
*molly_ptr = (struct student)
.name = "molly",
.age = 25
;
【讨论】:
【参考方案2】:使用复合文字:
*molly_ptr = ( struct student ) .name = "molly", .age = 25 ;
这几乎等同于:
struct student temp = .name = "molly", .age = 25 ;
*molly_ptr = temp;
【讨论】:
非常有趣,尽管this 源表明指向的数据现在在堆栈上。鉴于上面的代码,这将导致内存泄漏。我不知道这种语法。 @sherrellbc 不正确。 molly_ptr 仍然指向分配的内存。整个结构被复制到该内存中。这在我的第二个例子中非常清楚。 这是我非常感兴趣的事情,我不知道你们谁是对的。如果这是 C++ 代码,我可以看到它被复制,但由于这是 C,我认为指针只是指向堆栈上的某个东西。有什么可以澄清的吗?它本身可能会成为一个很好的问题。 @callyalater,我们取消引用指向struct student
对象的指针,并且赋值将结构体的深层复制到内存中。根据我对文档的了解,复合文字创建了一个未命名的对象(自动或静态持续时间取决于其内容和修饰符),并且编译器生成深层复制指令。阅读 this 文档的最后两段,了解 C++ 中的陷阱。
@sherrellbc:有趣的是,在链接的 asm 中,复合文字赋值和它自己的赋值如何创建相同的程序集。以上是关于在堆中使用指定的初始化器的主要内容,如果未能解决你的问题,请参考以下文章