为什么我们可以在函数内部初始化并仍然在函数外部使用该值?
Why can we initialize inside a function and still use that value outside the function?
例如:
#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以及栈和堆的区别。当我们在函数alloc_and_init_some_thing
中声明并初始化变量si
时,这个值不是已经存在于栈中了吗?因此它应该在函数完成时被清除?
但我可以看到这实际上并没有发生。回到主函数,当我们打印 s->n
时,我们得到值 41
.
类似地,当我们在主函数中打印 *i
的值时,它会打印 21
.
这是为什么?
行 memcpy(*s, &si, sizeof(**s));
将堆栈上的结构 si
复制到堆分配结构 s
中,从而使其持久存在内存中,因为可以在堆分配中的任何位置访问程序。它只是一个指向内存中地址的指针。
同样的事情发生在类似的功能中。
你是对的,"si" 和 "j" 的生命周期仅限于它们各自的功能,并且在这些功能的 return 之后不可用。但是,它们的内容已在函数 return 之前通过 malloc/memcpy 复制,并且指向副本的指针存储在变量 "s" 和 "i" 中,它们仍然存在在打印(或使用)这些副本时。
例如:
#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以及栈和堆的区别。当我们在函数alloc_and_init_some_thing
中声明并初始化变量si
时,这个值不是已经存在于栈中了吗?因此它应该在函数完成时被清除?
但我可以看到这实际上并没有发生。回到主函数,当我们打印 s->n
时,我们得到值 41
.
类似地,当我们在主函数中打印 *i
的值时,它会打印 21
.
这是为什么?
行 memcpy(*s, &si, sizeof(**s));
将堆栈上的结构 si
复制到堆分配结构 s
中,从而使其持久存在内存中,因为可以在堆分配中的任何位置访问程序。它只是一个指向内存中地址的指针。
同样的事情发生在类似的功能中。
你是对的,"si" 和 "j" 的生命周期仅限于它们各自的功能,并且在这些功能的 return 之后不可用。但是,它们的内容已在函数 return 之前通过 malloc/memcpy 复制,并且指向副本的指针存储在变量 "s" 和 "i" 中,它们仍然存在在打印(或使用)这些副本时。