我正在使用这些功能实现链接列表:
struct node{
int data;
struct node *next;
};
struct list{
struct node *head;
};
struct list* list_init(){
struct list *lst;
lst = malloc (sizeof(struct list));
lst->head = 0;
};
list_add(struct list *l, int num){
struct node *point;
point = malloc(sizeof(struct node)):
if (&point == NULL){
return 1;
}
else {
point->data = num;
point->next = l->head;
l->head = point;
return 0;
}
};
void list_print(struct list *l){
struct node *point = l->head;
while (point != 0) {
printf("value = %d and next pointer = %p\n", point->data, point->next);
point = point->next;
}
};
void list_cleanup(struct list l*){
struct node *point;
struct node *temp;
while (point != 0);
temp = point;
point = point->next;
free(temp);
}
};
我不明白为什么当我运行主要时:
int main(int argc, char *argv[]) {
struct list *a;
a = list_init();
list_add(a, 10);
list_add(a, 53);
list_add(a, 66);
list_print(a);
list_cleanup(a);
list print(a);
输出将是:
66 0x10570b0
53 0x1057090
10 (nil)
17133760 0x10570b0
17133728 0x1057090
17122696 (nil)
我理解前3个输出值,它们是链接列表中指针值的值。但是,通过循环遍历列表并释放内存后,list_print()stil如何输出正确的指针值和列表的正确长度?释放内存后,这是不可能的?
答案 0 :(得分:2)
free()
不会删除或清零内存。它使它可用于以后的分配。
7.20.3.2-2
free函数导致ptr指向的空间被释放,即可用于进一步分配。
但是,如果指针指向无效的内存空间,则结果既不是崩溃也不是特定结果,而是未定义的行为:
6.5.3.2-4:
[...]如果为指针指定了无效值,则unary *运算符的行为未定义.87)
Fn 87:
[...] unary *运算符解除引用指针的无效值是空指针,地址与指向的对象类型不对齐,对象的地址结束后寿命
Fn 83:
83)如果& E是一个有效的指针表达式(其中&是''address-of''运算符,它生成一个指向其操作数的指针),表达式(& E) - > MOS是与E.MOS相同。
由于它是未定义的行为,因此包括正确打印列表在内的每个行为都符合标准。
引自:http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf
答案 1 :(得分:1)