我正在阅读和学习C.我已经阅读了许多类似的问题,但大多数似乎都是我所遇到的反例,或者我仍然不理解堆上对象分配的概念。在堆栈上。
假设我有一个类似于以下示例的结构:
typedef struct {
int x;
char* word;
struct list_element* next;
}list_element;
我想编写一个初始化struct
类型list_element
的函数。
我从教科书中学到的东西是使用malloc
在堆上创建结构,所以在初始化函数之外一切都仍然可见。
list_element* init_list_element(int x, char* word) {
list_element* le = (list_element*)malloc(sizeof(list_element));
le->word = word;
le->x = x;
return le;
}
为了真正理解这个主题,我尝试编写一个替代的初始化函数,在堆栈上分配struct
。以后在尝试访问属性时应该导致错误,因为变量应该超出范围。
list_element init_list_element(int x, char* word) {
list_element le;
le.word = word;
le.x = x;
return le;
}
然而,当使用第二个实现创建结构并尝试访问例如属性x时,代码不会中断。为什么是这样?变量le
是否应该超出范围,因此在尝试printf其属性时无法访问?
list_element test = init_list_element(123,"test");
printf("%s, %i", test.word, test.x);
答案 0 :(得分:2)
list_element test = init_list_element(123,"test");
您正在创建在第二个函数内创建的结构的副本,因此您仍然可以访问它,但它只是一个副本。
在C中,您为变量指定的所有内容都是副本。
示例:
list_element le1 = {1, NULL, NULL};
list_element le2 = le1;
le2将包含le1的副本,而不是原始的le1。换句话说,以下内容不会改变le1的值:
le2.x = 3;
printf("%d",le1.x); // 1
printf("%d",le2.x); // 3
答案 1 :(得分:1)
变量le
已超出范围,但您无法访问le
。 init_list_element()
函数返回le
的副本,该副本的内容已分配给test
。
test
的成员会包含le
最初所做的相同数据。