用strdup()修复代码

可以用strdup()修复原来的create()函数:

  1. island* create(char *name)
  2. {
  3. island *i = malloc(sizeof(island));
  4. i->name = strdup(name);
  5. i->opens = "09:00";
  6. i->closes = "17:00";
  7. i->next = NULL;
  8. return i;
  9. }

你会发现我们只需要对name字段使用strdup()函数就行了,知道为什么吗?

因为我们把openclose字段设为了字符串字面值。还记得存储器的分布图吗?字符串字面值位于存储器的只读区域,该区域专门用来分配常量。把openclose的值设为常量,即使不复制也无所谓,因为它们不会改变。但为了防止出错必须复制name数组,因为后面的代码可能修改它。

这里没有蠢问题

问:如果island结构用数组保存岛名,而不是字符指针,还需要用strdup()吗?

:不需要,如果用数组,每个island结构都会保存自己的副本,不需要你自己创建。

问:那为什么要在数据结构中使用字符指针而不是字符数组呢?

:字符指针不会限制字符串的大小。如果用字符数组,需要提前决定字符串的长度。

能改好吗?

为了验证这些修改能否修复代码,我们再次运行原来的代码:

用strdup()修复代码 - 图1

现在,代码正确工作了。用户每输入一个岛名,create()函数都把它保存在了新的字符串中。

好了,创建岛屿数据的函数你已经有了,我们用它来根据文件创建链表。

用strdup()修复代码 - 图2游泳池拼图

真倒霉!用来创建飞行之旅的代码掉进了游泳池!你的任务是从泳池中取出代码片段,填入以下的空白横线处。你的目标是重构程序,程序从标准输入读取一列岛名,然后将它们连成链表。每个代码片段只能使用一次,但不是所有片段都用得到。

用strdup()修复代码 - 图3

用strdup()修复代码 - 图4游泳池拼图解答

真倒霉!用来创建飞行之旅的代码掉进了游泳池!你的任务是从泳池中取出代码片段,填入以下空白横线处。你的目标是重构程序,程序从标准输入读取一列岛名,然后将它们连成链表。

用strdup()修复代码 - 图5

用strdup()修复代码 - 图6磨笔上阵

等等!还没完呢。别忘了,只要用malloc()函数分配了空间,就需要用free()函数释放它们。到目前为止,程序用malloc()在堆上创建了island链表,但当用完时没有释放这些空间,下面来写这部分代码。

以下是release()函数的开头部分,只要把第一座岛的指针传给它,release()就会释放链表使用的所有存储器:

用strdup()修复代码 - 图7

好好想想,释放存储器时,要释放哪些东西?只有island,或者还有其他东西?应该按什么顺序释放它们?

 

用strdup()修复代码 - 图8磨笔上阵解答

等等!还没完呢。别忘了,只要用malloc()函数分配了空间,就需要用free()函数释放它们。到目前为止,程序用malloc()在堆上创建了island链表,但当用完时没有释放这些空间,下面来写这部分代码。

以下是release()函数的开头部分,只要把第一座岛的指针传给它,release()就会释放链表使用的所有存储器:

用strdup()修复代码 - 图9

释放存储器时,要释放哪些东西?只有island,或者还有其他东西?应该按什么顺序释放它们?