C链接列表大小不受malloc限制

时间:2016-06-12 00:11:09

标签: c pointers linked-list malloc

我使用以下代码创建了一个链接列表。正如您所看到的,我已经使用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;
}

当我编译并运行代码时,获得的结果是,

done 1
done 2
0   1   2   3   154208560   842282289   876087600   154744882   808859448   875837236
done 3

为什么我能够为第4个节点分配值并在实际创建大小为3的列表时访问它?

我看到垃圾值正在从第5个节点访问到第10个节点。但是如何创建第4个节点?

P.S:

我知道10!= 3。当我将循环置于其限制内时,代码正常运行。我想看看当我们走出界限时会发生什么。我看到第4个节点也被创建了,因为当我实际创建一个大小为3的列表时,我能够分配值。

这纯粹是为了看我是否会遇到段错误。

2 个答案:

答案 0 :(得分:7)

您正在调用undefined behavior。执行此操作时,程序可能会崩溃,它可能看起来正常工作,或者它可能以看似随机的方式运行。

C不对数组或已分配的内存执行任何类型的边界检查。这是让它变得快速的事情之一。这也意味着它将允许你做你不应该做的事情。它相信程序员“做正确的事”。

在您的特定计算机上,您会在第三个元素后看到随机数据。当我在我的机器上运行相同的代码时,我碰巧得到了预期的输出,就像分配了足够的内存一样。此外,如果我取消对free的调用,则程序崩溃。这是未定义的行为。

试图理解未定义的行为通常是徒劳的。这完全取决于编译器及其运行的机器的实现细节。在这种情况下,写入的内存可能是在正确分配的内存之后堆中的未分配内存。根据malloc的实现方式,内存的这一部分可能包含malloc和其他函数正常运行所需的数据。重点是写在数组末尾不能保证崩溃,所以你需要小心。

答案 1 :(得分:1)

此代码在不同的操作系统上的行为会有所不同。

即使分配了所有10个整数并正确打印,您也可能会离开。

您的代码将列表的开头放在堆上,只有3个元素的分配。

你可能会幸运并为所有10个元素使用内存,否则你的程序将在第4个版本中崩溃!