I have changed my function like this. I think I don't need to return pointer to node, I just need data from it. So I can free node while retrive my data.
That's my whole double-cross link list code:
//
//  double_linklist.c
//  tt
//
//  Created by tarrant on 2019/2/16.
//  Copyright © 2019 tarrant. All rights reserved.
//
#include "double_linklist.h"
static void c_free(void *p){
    free(p);
    p=NULL;
}
static Node *direct_to_index(List plist,long index){
    Node *pnode;
    unsigned int count = list_count(plist);
    if (labs(index) > count+2){
        fprintf(stderr, "index out of scope.");
        return NULL;
    }
    if (index >=0){
        if(plist->head==NULL){
            pnode=plist;
        }
        else
            pnode=plist->head;
        while (true){
            if(--index<0)
                break;
            else
                if (pnode->next!=NULL)
                    pnode=pnode->next;
                else{
                    fprintf(stderr, "invalid node %p.",pnode);
                    return NULL;
                }
        }
    }
    else{
        if(plist->tail==NULL){
            pnode=plist;
        }
        else
            pnode=plist->tail;
        while (true){
            if(++index>=0)
                break;
            else
                if (pnode->prev!=NULL)
                    pnode=pnode->prev;
                else{
                    fprintf(stderr, "invalid node %p.",pnode);
                    return NULL;
            }
        }
    }
     return pnode;
}
static Node *direct_to_head(List plist){
    return direct_to_index(plist, 0);
}
static Node *direct_to_tail(List plist){
    return direct_to_index(plist, -1);
}
void empty_list(List plist){
    Node *tmp,*current;
    plist=direct_to_head(plist);
    current=plist->next;
    while (current->next!=NULL) {
        if(current->data!=NULL){
            c_free(current->data);
        }
        tmp=current;
        current=current->next;
        c_free(tmp);
    }
    current->prev=plist;
    plist->next=current;
}
List init_list(void){
    Node *head,*tail;
    if((head = (Node *)calloc(1, sizeof(Node)))!=NULL){
        tail = (Node *)calloc(1, sizeof(Node));
        head->tail=tail;
        head->data=(unsigned int *)calloc(1, sizeof(unsigned int));
        head->next=tail;
        if(tail!=NULL){
            tail->prev=head;
            tail->data=NULL;
            tail->head=head;
            return head;
        }
    }
    fprintf(stderr, "No space in initing.");
    return NULL;
}
bool isempty_node(const Node *pnode){
    if(pnode->data==NULL)
        return true;
    return false;
}
bool free_node(Node *pnode){
    unsigned int *count;
    Node *next,*prev;
    if(pnode->next==NULL ||pnode->prev==NULL){
        fprintf(stderr, "You are empting head,tail or invaild node.");
        return false;
    }
    count=direct_to_head(pnode)->data;
    next=pnode->next;
    prev=pnode->prev;
    next->prev=prev;
    prev->next=next;
    c_free(pnode);
    c_free(pnode->data);
    --*count;
    return true;
}
void free_all_empty_nodes(List plist){
    Node *phead;
    unsigned int count=0;
    phead=direct_to_head(plist)->next;
    while (phead->next!=NULL) {
        if((phead->data==NULL)&&(free_node(phead)==false))
            fprintf(stderr, "error in empting index %d",count);
        phead=phead->next;
        count++;
    }
}
Node *pop_node(List plist,long index){
    Node *pnode,*next,*prev;
    if (index>=0)
        index++;
    else
        index--;
    pnode=direct_to_index(plist, index);
    next=pnode->next;
    prev=pnode->prev;
    pnode->head=NULL;
    pnode->tail=NULL;
    next->prev=prev;
    prev->next=next;
    return pnode;
}
unsigned int list_count(List plist){
    unsigned int *count;
    Node *phead;
    if(plist->head==NULL){
        phead=plist;
    }
    else
        phead=plist->head;
    count=phead->data;
    return *count;
}
void insert_list(const void *data,List plist,size_t size,long index){
    Node *tmp,*current;
    unsigned int *count;
    if(data==NULL){
        fprintf(stderr, "data is empty.");
        return;
    }
    tmp=(Node *)calloc(1, sizeof(Node));
    tmp->data=(void *)calloc(1, size);
    if(tmp==NULL||tmp->data==NULL){
        fprintf(stderr, "no space for allocation.\n");
        return;
    }
    memcpy(tmp->data,data,size);
    if (index<0)
        index--;
    current=direct_to_index(plist, index);
    tmp->next=current->next;
    current->next->prev=tmp;
    current->next=tmp;
    tmp->prev=current;
    tmp->head=direct_to_head(current);
    tmp->tail=direct_to_tail(current);
    count=direct_to_head(plist)->data;
    ++*count;
}
void append_list(const void *data,List plist,size_t size){
    insert_list(data,plist,size,-1);
}
bool modify_node(Node *node,const void *data,size_t size){
    if((data==NULL)||(node->prev==NULL)||(node->next)==NULL)
        return false;
    free(node->data);
    node->data=(void *)malloc(size);
    memcpy(node->data,data,size);
    return true;
}
bool modify_list(const void *data,List plist,long index,size_t size){
    Node *phead;
    if(data==NULL)
        return false;
    if (index>=0)
        index++;
    else
        index--;
    phead=direct_to_index(plist, index);
    return modify_node(phead,data,size);
}
void traverse_list(const List plist,void (*pfun)(void *pdata),int flag){
    Node *pnode;
    if(flag>=0){
        pnode=direct_to_head(plist)->next;
        while (pnode->next!=NULL) {
            (pfun)(pnode->data);
            pnode=pnode->next;
        }
    }
    else{
        pnode=direct_to_tail(plist)->prev;
        while (pnode->prev!=NULL) {
            (pfun)(pnode->data);
            pnode=pnode->prev;
        }
    }
}