C语言#bug#双向链表尾部插入

如图:

  • 1、正确的,下意识认为的
  • 2、bug的,实际发生的。

在这里插入图片描述
测试代码:

#include "gtest/gtest.h"
#include "mockcpp/mokc.h"

#include "linux/list.h"
#include <cstdlib>

#define TEST_PRINT

#ifdef TEST_PRINT
#define TEST_LOG_PRINT(x) std::cout << "res is [" << x << "]"
#define TEST_LOG_PRINT2(x) std::cout << "res is [" << x << "]\n"
#endif // TEST_PRINT

TEST(linux_list, basic)
{
    head_t list;
    // Act#01:  空链表 ---> 指向自身
    INIT_LIST_HEAD(&list);
    // assert#01:
    EXPECT_EQ(list.prev, &list);
    EXPECT_EQ(list.next, &list);
}

TEST(linux_list, add_tail)
{
    struct TestBuffer
    {
        int val;
        list_head list;
    };

    // Act: 链表链接10个元素: 0 1 2 ... 9
    list_head *head = NULL;
    for (int i = 0; i < 10; i++)
    {
        TestBuffer *buff = (TestBuffer *)malloc(sizeof(*buff));
        buff->val = i;
        INIT_LIST_HEAD(&buff->list);
        if (i == 0)
            head = &buff->list;
        else
        {
            list_add_tail(&buff->list, head);
        }
    }

    // Assert: 注意,第1个元素被当做表头了,所以遍历不到。
    TestBuffer *cusor = NULL;
    int i = 1;
    TEST_LOG_PRINT2("fff");
    list_for_each_entry(cusor, head, list)
    {
        EXPECT_EQ(cusor->val, i++);
        TEST_LOG_PRINT(cusor->val);
    }
    std::cout << "\n";
}

List相关:简化版linux/list.h
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_LIST_H
#define _LINUX_LIST_H

struct list_head {
	struct list_head *next, *prev;
};
`/**
 * INIT_LIST_HEAD - Initialize a list_head structure
 * @list: list_head structure to be initialized.
 *
 * Initializes the list_head to point to itself.  If it is a list header,
 * the result is an empty list.
 */
static inline void INIT_LIST_HEAD(struct list_head *list)
{
	WRITE_ONCE(list->next, list);
	WRITE_ONCE(list->prev, list);
}

/**
 * list_add_tail - add a new entry
 * @new: new entry to be added
 * @head: list head to add it before
 *
 * Insert a new entry before the specified head.
 * This is useful for implementing queues.
 */
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
	__list_add(new, head->prev, head);
}
/*
 * Insert a new entry between two known consecutive entries.
 *
 * This is only for internal list manipulation where we know
 * the prev/next entries already!
 */
static inline void __list_add(struct list_head *new,
			      struct list_head *prev,
			      struct list_head *next)
{
	if (!__list_add_valid(new, prev, next))
		return;

	next->prev = new;
	new->next = next;
	new->prev = prev;
	WRITE_ONCE(prev->next, new);
}
``
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值