例如:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
typedef struct {
int n;
double d;
} some_thing;
void alloc_and_init_some_thing(some_thing** s, int n, double d) {
some_thing si = { .n=n, .d=d };
*s = malloc(sizeof(**s));
memcpy(*s, &si, sizeof(**s));
}
void alloc_and_init_int(int **i) {
int j = 21;
*i = malloc(sizeof(**i));
memcpy(*i, &j, sizeof(**i));
}
int main() {
some_thing *s;
alloc_and_init_some_thing(&s, 41, 31);
printf("s->n=%d s->d=%f\n", s->n, s->d);
int *i;
alloc_and_init_int(&i);
printf("*i=%d\n", *i);
return 0;
}
我仍在学习C以及堆栈和堆之间的区别。当我们在函数si
中声明并初始化变量alloc_and_init_some_thing
时,堆栈中是否不存在该值?因此,当函数完成时应该清除掉它吗?
但是我可以看到实际上并没有发生。回到主函数中,当我们打印s->n
时,我们得到的值是41
。
类似地,当我们在主函数中打印*i
的值时,它也会打印21
。
那是为什么?
答案 0 :(得分:3)
第memcpy(*s, &si, sizeof(**s));
行将堆栈上的结构si
复制到堆分配的结构s
中,因此由于可以在程序中的任何位置访问堆分配,因此使其持久化在内存中。它只是指向内存中地址的指针。
类似的功能也会发生同样的事情。
答案 1 :(得分:1)
您是正确的,“ si”和“ j”的生存期仅限于它们各自的功能,并且在从这些功能返回后不可用。但是,它们的内容已在返回函数之前通过malloc / memcpy复制,并且指向副本的指针存储在变量“ s”和“ i”中,在打印(或使用)变量时它们仍然有效副本。