Asp*_*nt9 1 c malloc pointers linked-list
我用以下代码创建了一个链表.正如你所看到的,我已经使用malloc创建了一个大小为3的列表.但我运行了大小为10的for循环来初始化和打印.
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
struct node {
int value;
struct node *next;
};
int main() {
//code
struct node **head;
struct node *curr;
curr = (struct node *) malloc(sizeof(struct node)*3);
head = &curr;
printf("done 1\n");
(*head)->value = 0;
(*head)->next = NULL;
for(int i = 1; i < 10; i++) {
(*head+i-1)->next = (*head+i);
(*head+i)->value = i;
(*head+i)->next = NULL;
}
curr = *head;
printf("done 2\n");
for(int i = 0; i < 10; i++) {
printf("%d\t", (*head + i)->value);
//curr = curr->next;
}
printf("\ndone 3\n");
//free(curr);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我编译并运行代码时,获得的结果是,
done 1
done 2
0 1 2 3 154208560 842282289 876087600 154744882 808859448 875837236
done 3
Run Code Online (Sandbox Code Playgroud)
为什么我能够为第4个节点分配值并在实际创建大小为3的列表时访问它?
我看到垃圾值正在从第5个节点访问到第10个节点.但是如何创建第4个节点?
PS:
我知道10!= 3.当我将循环置于其限制内时,代码正常运行.我想看看当我们走出界限时会发生什么.我看到第4个节点也被创建,因为当我实际创建一个大小为3的列表时,我能够分配值.
这纯粹是为了看看我是否会遇到段故障.
您正在调用未定义的行为.执行此操作时,程序可能会崩溃,它可能似乎正常工作,或者它可能以看似随机的方式运行.
C不对数组或分配的内存执行任何类型的边界检查.这是让它变得快速的事情之一.这也意味着它将允许你做你不应该做的事情.它相信程序员"做正确的事".
在您的特定计算机上,您会看到第三个元素之后的随机数据.当我在我的机器上运行相同的代码时,我碰巧得到了预期的输出,就像分配了足够的内存一样.此外,如果我取消对该调用的注释free
,程序将崩溃.这是未定义的行为.
试图理解未定义的行为通常是徒劳的.这完全取决于编译器及其运行的机器的实现细节.在这种情况下,写入的内存可能是在正确分配的内存之后堆中的未分配内存.根据malloc的实现方式,内存的这一部分可能包含malloc和其他函数正常运行所需的数据.关键是写在数组末尾不能保证崩溃,所以你需要小心.