当做我们操作堆地址的时候,遇到两个难题:
1、堆地址作为形参传入,在api修改其值时当api生命周期结束。在上层打印其值,其值已变化。【堆地址全局有效】
2、当把一级指针,其值为null的变量作为形参传入api,当生命周期结束。在上层打印,其值任为null。
【在下层接口获取堆地址,需取地址符号&,才能获取到malloc的地址】
typedef struct sys_comm_list_s
{
void *data;
struct sys_comm_list_s *next;
}sys_comm_list_t;
#define COMMM_LIST_NEW(void) \
sys_comm_list_new(void)
#define COMM_LIST_INSERT(head, data) \
sys_comm_list_insert(head, (void*)(data))
#define COMM_LIST_FROEACH(head, list, list_data) \
for (list = head; list && (list_data = list->data); list = list->next)
#define COMM_LIST_FREE(head) \
sys_comm_list_free(head)
extern sys_comm_list_t *sys_comm_list_new(void);
extern sys_comm_list_t *sys_comm_list_insert(sys_comm_list_t *head, void *data);
extern sys_comm_list_t *sys_comm_list_free(sys_comm_list_t **head);
//申请list node节点
sys_comm_list_t *sys_comm_list_new(void)
{
sys_comm_list_t *head = (sys_comm_list_t*)malloc(sizeof(sys_comm_list_t));
head->data = NULL;
head->next = NULL;
return head;
}
//head头插入节点
sys_comm_list_t *sys_comm_list_insert(sys_comm_list_t *head, void *data)
{
sys_comm_list_t *new = NULL;
sys_comm_list_t *tmp = head->next;
if (!head || !data)
return NULL;
if (NULL == head->data)
{
head->data = (void*)data;
head->next = NULL;
}
else
{
new = sys_comm_list_new();
new->data = (void*)data;
new->next = NULL;
head->next = new;
new->next = tmp;
}
return head;
}
//list释放堆地址
sys_comm_list_t *sys_comm_list_free(sys_comm_list_t **head)
{
sys_comm_list_t *tmp = NULL;
sys_comm_list_t *node = NULL;
if (!head)
return NULL;
node = *head;
while(node)
{
tmp = node;
if (node->data)
{
free(node->data);
node->data = NULL;
}
node = node->next;
free(tmp);
}
return (*head = NULL);
}
使用例子:
//初始化head节点
infoDb.list = COMMM_LIST_NEW();
//申请data数据
node = (sys_l3_data_t*)malloc(sizeof(sys_l3_data_t));
if (node)
memset(node, 0, sizeof(sys_l3_data_t));
//插入数据
COMM_LIST_INSERT(infoDb.list, node);
//遍历数据
sys_comm_list_t *list = NULL;
sys_l3_data_t* node = NULL;
COMM_LIST_FROEACH(infoDb.list, list, node)
{
/*
data 数据操作,,,,,,,
*/
}
c语言单向链表操作
于 2022-11-21 16:34:17 首次发布