1、链表节点的动态分配
下面代码在执行地62行的打印语句时,发现链表L
中的一个节点信息突然发生了变化,下图是打印语句执行前后链表L
的变化对比图:
这个过程中明明没有对链表L
进行操作,为什么会改变其节点信息呢?后来了解到该链表的节点是在另一个函数中通过LNode node;
的方式创建的,这样做的结果是变量node为局部变量,保存在栈中,当退出创建该节点的函数后,这个节点所在的栈空间将被释放。 之前没有出问题是由于这片空间暂未被再次使用,所以在打印语句之前看上去一切正常,直到执行打印语句时这片空间被打印语句当作缓冲区利用,导致内存地址中的值发生改变,也就发生了图二的情况。
2、链表节点的释放
在下面的程序中,释放链表中的节点时出现错误:Trace/breakpoint trap

经了解后发现s所指向的节点也是采用DNode node;
的方式创建的,该变量同样保存在函数栈区,而free函数是用于释放堆区的空间的,导致在这里用于释放栈区的变量时出错。
其实很好理解,局部变量都保存在了栈区,当函数结束时,它所在的函数栈会被回收,该函数中的局部变量也都会回收,所以无需采用free函数去回收局部变量。而malloc申请的空间位于堆区,这个区域的数据由程序员通过malloc申请,之后即使函数退出也依然保留着不会被自动回收,所以创建链表后,在其他函数中访问可以正常的访问链表。但也正是因为malloc申请的空间不会被自动回收,才需要程序员通过free函数手动去回收,否则,可以想象这样的一个后台程序,它每秒会创建一个1MB的节点并在1秒后回收,但写这个代码的程序员忘记用free回收了,假如这个程序持续运行1小时,那将有60x60=3600MB(3个多G)的内存空间被持续占用而得不到释放,这种内存泄漏是很严重的问题。
在创建链表时,采用malloc在堆区给节点分配内存,使链表在全局都可以被访问,但同样要记得在用完后使用free函数回收,避免内存泄漏。