Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C “此”中缺少free();“好品味”;及;“品味差”;密码?_C_Linked List - Fatal编程技术网

C “此”中缺少free();“好品味”;及;“品味差”;密码?

C “此”中缺少free();“好品味”;及;“品味差”;密码?,c,linked-list,C,Linked List,在一次关于Linus Torvalds的采访中,他分享了“良好品味”的重要性。他用下面的代码解释了好品味 带有“低级趣味”的代码 具有“良好品味”的代码 两个示例都没有使用free()释放要删除的节点的内存。有人能告诉我为什么代码是这样写的吗?还是我对C或链表的概念有误?注意此函数的语义也很重要。其目的是从列表中删除节点,而不是像您在问题中建议的那样删除节点。至少函数名暗示了这一点。如果它删除了该节点而没有公布该语义,我会感到惊讶 此外,我们无法单独知道对象是如何分配的,因此函数不能合理地假

在一次关于Linus Torvalds的采访中,他分享了“良好品味”的重要性。他用下面的代码解释了好品味

带有“低级趣味”的代码

具有“良好品味”的代码


两个示例都没有使用
free()
释放要删除的节点的内存。有人能告诉我为什么代码是这样写的吗?还是我对C或链表的概念有误?

注意此函数的语义也很重要。其目的是从列表中删除节点,而不是像您在问题中建议的那样删除节点。至少函数名暗示了这一点。如果它删除了该节点而没有公布该语义,我会感到惊讶

此外,我们无法单独知道对象是如何分配的,因此函数不能合理地假设它是一个堆对象,并且
free()
it-如果对象是静态的,这将导致运行时错误


调用方可能正在从列表中删除对象并继续使用它,此函数负责维护列表,而不是列表中独立存在的对象。
条目的所有者有责任管理其内存。

在这种情况下,极简主义正是良好品味的体现;第二个例子没有第一个那么华丽,更切题。糟糕的代码中有一些错误,但关键是额外的变量和if语句是多余的

品味是一种主观品质,有很多理由支持这两种方式。对我来说,品味一直是关于可读性的。可读性并不明显支持这两种方法——TLDR与太复杂;没有打扰(TC;DB)


编译器技术对品味有着时尚专家的影响。很久以前,当窥视孔优化是一件事,第二个版本是首选;它生成的代码要少得多。在不太旧的年代,编译器们玩弄数据流分析,喜欢第一个版本,因为它的指针追踪显然不是隐藏的别名(与第二个不同)。现代编译器拥有大量内存和cpu,可以进行更好的别名检查,因此已经回到了第一代。即使如此,在您的示例中,它仍然有3种不同的说明。

您能提供面试的链接/参考吗?这取决于列表的总体设计。从列表中删除一个节点并不意味着该节点可能不再使用。撇开样式不谈,上面的示例是否已损坏?您可以找到一个关于指针-指针链表处理技术的问题,在该技术中,指针-指针链表处理技术被关闭为。@500 InternalServerError的副本。两者都只是伪代码。我不希望他们中的任何一个是完整的。在真正的“好品味”示例中,
head
可能不是全局变量。并且还将包括一些
NULL
检查。并且free()它-如果对象是静态的,则会导致运行时错误:释放未由
malloc
和friends分配的内容不一定会触发运行时错误,这只是UB。@Jabberwocky这将是一个在构建时未捕获的语义错误。从这个意义上讲,是在运行时发生的错误。这就是我的意思,不一定是运行时环境显式捕获的错误。我希望这是清楚的?这对我来说是(而且一直是)清楚的,但对OP来说可能不清楚。@Jabberwocky谢谢,你的评论有助于澄清。
remove_list_entry(entry)
{
    prev = NULL;
    walk = head;

    // Walk the list

    while (walk != entry) {
        prev = walk;
        walk = walk->next;
    }

    // Remove the entry by updating the head
    // or the previous entry

    if (!entry)
        head = entry->next;
    else
        prev-next = entry->next;
}
remove_list_entry(entry)
{
    // The "indirect" pointer points to the
    // *address* of the thing we'll update

    indirect = &head;

    // Walk the list, looking for the thing that
    // points to the thing we want to remove

    while ((*indirect) != entry)
        indirect = &(*indirect)->next;

    // .. and just remove it
    *indirect = entry->next;
}