一不小心就对未分配的内存进行访问和修改

问题出自《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 的 有些 实现中,它们以链表的形式维护可用的内存池。对分配的内存之外的区域进行访问可能会破坏这个链表,这有可能产生异常,从而终止程序。

posted @ 2019-03-27 11:47  BMing  阅读(401)  评论(0编辑  收藏  举报