问题出自《c 和指针》第十二章问题4: "讨论一些技巧,怎么省略双链表中根节点的值字段“
typedef struct NODE{
struct NODE * pwd;
struct NODE * nwd;
type value;
}Node;
习题答案第一种方法便是 给根节点这样分配内存 Node *root = (Node *)malloc(sizeof(Node) - sizeof(type) );
这样确实是没有对value进行内存分配。也可以对根节点的pwd、nwd进行访问和修改,只要你不去访问根节点的value就不会对未分配的内存越界操作。
但是如果结构体是这样声明的:
typedef struct NODE{
struct NODE * pwd;
type value;
struct NODE * nwd;
}Node
根节点的起始位置是556810848 也就是第一个元素的位置,而第二个需要的元素中间隔了一个要省略的元素。这样的话就导致访问第二个元素时访问了未分配的内存地址:556810864 导致越界访问
总结:如果想要在malloc上做手脚来省略某个字段的话,就要把这个字段放在最末尾。不然通过结构体访问它后面的非省略元素会导致越界访问。对未分配的动态内存进行非法访问可能会有以下两种问题:
1.被访问的内存可能保存了其他变量的值。对它进行修改会破坏那个变量,这种bug很难发现。
2. 在malloc 和free 的 有些 实现中,它们以链表的形式维护可用的内存池。对分配的内存之外的区域进行访问可能会破坏这个链表,这有可能产生异常,从而终止程序。