C将void*数据强制转换为typedef结构

C将void*数据强制转换为typedef结构,c,pointers,data-structures,C,Pointers,Data Structures,我有一个BST库,其中存储了一些结构: struct bst_node { char *key; void* data; // this one i want to get it casted to struct model struct bst_node* left; struct bst_node* right; }; 以下是搜索函数,它返回驻留在bst.c中的bst\u节点: struct bst_node** search(

我有一个BST库,其中存储了一些结构:

struct bst_node {
    char *key;
    void* data;                // this one i want to get it casted to struct model
    struct bst_node* left;
    struct bst_node* right;
};
以下是搜索函数,它返回驻留在bst.c中的
bst\u节点

struct bst_node** search(struct bst_node** root,char *key) {
    struct bst_node** node = root;
    while (*node != NULL) {
        int compare_result = compare(key, (*node)->key);
        if (compare_result < 0)
            node = &(*node)->left;
        else if (compare_result > 0)
            node = &(*node)->right;
        else
            break;
    }
    return node;
}
假设在main.c中,我搜索一个项目并返回一个包含我感兴趣的
void*
数据的树节点,我如何转换该数据并将其分配给一个模型,以便以后可以访问模型的字段(例如修改附件列表)

以下是我尝试的方法:

  • 返回数据

    model *m;
    m  = (model *)searches(root,mod);  // the searches function is similar to the search posted
    if (m != NULL) {                   //before but instead of a node returns &(*node)->data
        printf("\n--------%s\n",(*m).name);
    
  • 返回一个节点并将其数据分配给model*m指针

    model* m;
    struct bst_node** node  = search(root,mod);  //return the node containing the string
                                                 //in "mod" and assign node->data to m
    if (node != NULL) {  
         m=(*node)->data;
         print_list(m);             //this functions prints the accesories list
    }
    
  • 我肯定有办法解决这个问题,但我就是找不到任何帮助,我们将不胜感激

    -----------------------------------------------------------main.c------------------------------------

        #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "bst.h"
    
    
    #define MAX 50
    
    typedef struct accesori_t{
        char nome[MAX];
        int prezzo;
        struct accesori_t *next;    
    }accesori;
    
    typedef struct modello_t{
        char nome[MAX];
        char file_a[MAX];
        char date[MAX];
        int prezzo;
        accesori *acs;
    }modello;
    
    
    
    void stampa_lista(struct modello_t *m);
    void append_node(struct accesori_t *llist,char *nome, int prezzo);
    void stampa_modelli(struct bst_node* root);
    void salva_lista(struct bst_node* root,char *nf);
    void inserisci_modello(struct bst_node** root);
    void cancella_modello(struct bst_node** root);
    void inserisci_acs(struct bst_node** root);
    void cancella_acs(struct bst_node** root);
    //struct modello_t *cerca_modello();
    void stampa_affinita(struct bst_node* root);
    
    int main(int argc, char *argv[])
    {
        int menu=0;
    
        char nf[MAX];
    
        char *t;
        char nome[MAX];
        char file_a[MAX];
        char data[MAX];
        int prezzo,gg,mm,a,index=0;
    
    
        int prezzo_a;
        char nomea[MAX];
        struct accesori_t *head,*curr;
        struct accesori_t *tmp;
    
    
        FILE *fp;
        FILE *fa;
        fp=fopen("cars.txt","r+");
    
        struct modello_t *m;
        m = (struct modello_t *)malloc(sizeof(struct modello_t));
    
        struct bst_node* root=NULL;
    
    
    
        while(fscanf(fp,"%s %s %d %s",nome,data,&prezzo,file_a)!=EOF){
    
                strcpy((*m).nome,nome);
                strcpy((*m).file_a,file_a);
                strcpy((*m).date,data);
                (*m).prezzo=prezzo;
                //printf("%s\n",(*m).nome);                  
    
                fa=fopen((*m).file_a,"r+");
    
    
                m->acs=(struct accesori_t *)malloc(sizeof(struct accesori_t));
                while(fscanf(fa,"%s %d",nomea,&prezzo_a)!=EOF)
                {                   
                    append_node(m->acs,nomea ,prezzo_a);       
                    while(m->acs->next != NULL)
                        {
                            m->acs = m->acs->next;
                            //printf("\t%s --- %d\n",m->acs->nome,m->acs->prezzo);
    
                        }
                }
    
                insert(&root, m->nome, m);   
                close(fa);
    
        }
    
        while(1){
    
            printf("\n\t1.Stampa Lista modelli");  
            printf("\n\t2.Inserisci nuovo modello");
            printf("\n\t3.Cancella un modello");
            printf("\n\t4.Inserisci Accesorio");
            printf("\n\t5.Cancella Accesorio");
            printf("\n\t6.Salva la lista");
            printf("\n\t7.Stampa Affinita'");
            printf("\n\t0.EXIT");
            printf("\n\t"); 
            printf("\nINSERIRE SCELTA : ");
            scanf("%d",&menu);   
    
            switch(menu)
            {
                case 1:
                    stampa_modelli(root);
                    break;
    
                case 2:
                    inserisci_modello(&root);
                    break;
                case 3:
                    cancella_modello(&root);
                    break;
                case 4:
                    inserisci_acs(&root);
                    break;
                case 5:
                    cancella_acs(&root);
                    break;
                case 6:
                    salva_lista(root,nf);
                    break;
                case 7:
                    stampa_affinita(root);
                    break;
                case 0:
                    return;
    
            }
    
        }  
    
    
    
    
      delete_tree(root);
      close(fp);
      system("PAUSE");  
      return 0;
    }
    
    void append_node(struct accesori_t *llist,char *nome, int prezzo) {
        while(llist->next != NULL)
            llist = llist->next;
    
        llist->next = (struct accesori_t *)malloc(sizeof(struct accesori_t));
        llist->next->prezzo = prezzo;
        strcpy( llist->next->nome,nome);
        llist->next->next = NULL;
    }
    
    void stampa_lista(struct modello_t *m){
        while(m->acs->next != NULL)
        {
            m->acs = m->acs->next;
            printf("\t%s --- %d\n",m->acs->nome,m->acs->prezzo);
    
        }
    }
    
    void stampa_modelli(struct bst_node* root){
            preorder_traverse(root);
    }
    
    void inserisci_modello(struct bst_node** root){
    
        FILE *fa;
        struct modello_t *temp;
        char nomea[MAX];
        int prezzo_a;
        temp = (struct modello_t *)malloc(sizeof(struct modello_t));
    
        printf("\nInserire il nome : ");
        scanf("%s",temp->nome);
    
        printf("\nInserire il file degli accesori : ");
        scanf("%s",temp->file_a);
    
        printf("\nInserire la data di disponibilita' (gg/mm/aaaa) : ");
        scanf("%s",temp->date);
    
        printf("\nInserire il prezzo : ");
        scanf("%s",&temp->prezzo);
    
    
        printf("%s\n",(*temp).nome);                 
        fa=fopen(temp->file_a,"r");
    
    
                temp->acs=(struct accesori_t *)malloc(sizeof(struct accesori_t));
                while(fscanf(fa,"%s %d",nomea,&prezzo_a)!=EOF)
                {                   
                    append_node(temp->acs,nomea ,prezzo_a);       
                    while(temp->acs->next != NULL)
                        {
                            temp->acs = temp->acs->next;                                               
                        }
                } 
                insert(root, temp->nome, temp);   
    
        free(temp);
        close(fa);   
    }
    
    void cancella_modello(struct bst_node** root){
    
        char mod[MAX];
    
        printf("\nInserire il nome del modello da cancellare : ");
        scanf("%s",mod);
    
        struct bst_node** node = search(root,mod);
    
        if (*node != NULL) {
            delete(node);
        }
    
        preorder_traverse((*root));    
        free(node);       
    }
    void inserisci_acs(struct bst_node** root){
        char mod[MAX];
        char acs[MAX];
        int prezzo_a;
    
        //struct modello_t* m;
    
        printf("\nInserire il nome del modello: ");
        scanf("%s",mod);
    
        struct modello_t **r = searches(root,mod);
    
        struct modello_t *m = *r; 
        if(m != NULL) { 
            printf("\n--------%s\n",m->nome); 
        } 
    
        //struct modello_t *m;
        //m  = (struct modello_t *)searches(root,mod); //trovare come fare a far ritornare il void *data
    
        /*if (m != NULL) {
            printf("\n\nQuesto pezzo di programma e' ancora da rivedere in quanto ho dei problemi\n nel convertire void* data in struct modello\n\n" );
    
    
            //m=(*node)->data; // parte problematica
            //stampa_lista(m);
            printf("\n--------%s\n",(*m).file_a);
            printf("\nInserire il nome dell'accesorio da aggiungere: ");
            scanf("%s",acs);
            printf("\nInserire il prezzo dell'accesorio da aggiungere: ");
            scanf("%s",prezzo_a);
    
            while(m->acs->next != NULL)
            {
                m->acs = m->acs->next; 
                if(m->acs->next == NULL)
                    append_node(m->acs,acs ,prezzo_a);                                                   
            }
    
        }*/
        free(m);    
    
    }
    void cancella_acs(struct bst_node** root){
        char mod[MAX];
        char acs[MAX];
    
    
        //struct modello_t *m;
    
        printf("\nInserire il nome del modello: ");
        scanf("%s",mod);
    
        struct bst_node **node  = search(root,mod);
    
        if(*node == NULL) 
        { 
            puts("Not found"); 
        } else { 
            struct modello_t *m = (*node)->data; 
    
        if(m == NULL) 
        { 
            puts("Found, but data is NULL"); 
        } else { 
            printf("\n--------%s\n",m->nome); 
        } 
        }
    
        /*if (node != NULL) {
            printf("\nQuesto pezzo di programma e' ancora da rivedere in quanto\n ho dei problemi nel convertire void* data in struct modello\n" );
    
    
        m=(struct modello_t*)((*node)->data); // parte problematica
    
         printf("\n--------%s\n",m->prezzo);
        //stampa_lista(m);
    
        printf("\nInserire il nome dell'accesorio da cancellare: ");
        scanf("%s",acs);
    
    
             while(m->acs->next != NULL)
            {   
                if(strcmp(m->acs->next->nome, acs)){
                    if(m->acs->next->next==NULL)
                       m->acs->next==NULL;        
                    m->acs->next=m->acs->next->next;
                    break; 
                } 
                m->acs = m->acs->next; 
    
            }
        }*/
        free(node);   
    }
    
    void salva_lista(struct bst_node* root,char *nf){
        FILE *fp;
        FILE *fa;
        fp=fopen(nf,"w+");
        char na[MAX];
    
        struct modello_t *m;
        //m = (struct modello_t *)malloc(sizeof(struct modello_t));
    
        /*while(ritorna_nodi(root)) 
        {       m=ritorna_nodi(root)
    
                fprintf(fp,"%s %s %d %s",(*m).nome,(*m).date,(*m).prezzo,(*m).file_a);                              
                fa=fopen((*m).file_a,"w+"); 
    
                while(m->acs->next!=NULL)
                {                   
                    fprintf(fp,"%s %d ",m->acs->nome,m->acs->prezzo);
                    m->acs=m->acs->next;
                }
                close(fa);               
        }*/
        close(fp);  
    }
    stampa_affinita(struct bst_node* root)
    {
          stm_aff(root);   
    }
    
    #include <stdlib.h>
    #include <assert.h>
    #include <string.h>
    #include "bst.h"
    #include "data.h"
    
    
    struct bst_node* new_node(char *key,void* data) 
    {
        struct bst_node* result = malloc(sizeof(struct bst_node));
        assert(result);
        result->data = data;
        result->key=malloc(strlen(key)*(sizeof(char)));
        strcpy(result->key,key);
        result->left = result->right = NULL;
        return result;
    }
    
    int compare(void* left,void* right)
    {
        if (strcmp(left,right)<0)
        {
            return -1;
        }
        else if (strcmp(left,right)==0)
        {
            return 0;
        }
        else
        {
            return 1;
        }
    }
    
    
    
    void free_node(struct bst_node* node) 
    {
        assert(node);
        free(node);
        node = NULL;
    }
    
    struct bst_node** search(struct bst_node** root,char *key) {
        struct bst_node** node = root;
        while (*node != NULL) {
            int compare_result = compare(key, (*node)->key);
            if (compare_result < 0)
                node = &(*node)->left;
            else if (compare_result > 0)
                node = &(*node)->right;
            else
                break;
        }
        return node;
    }
    
    void* searches(struct bst_node** root,char *key) {
        struct bst_node** node = root;
        while (*node != NULL) {
            int compare_result = compare(key, (*node)->key);
            if (compare_result < 0)
                node = &(*node)->left;
            else if (compare_result > 0)
                node = &(*node)->right;
            else
                break;
        }
        return (*node)->data;
    }
    
    void insert(struct bst_node** root,char *key, void* data) {
        struct bst_node** node = search(root,key);
        if (*node == NULL) {
            *node = new_node(key,data);
        }
    }
    
    void delete(struct bst_node** node) {
        struct bst_node* old_node = *node;
        if ((*node)->left == NULL) {
            *node = (*node)->right;
            free_node(old_node);
        } else if ((*node)->right == NULL) {
            *node = (*node)->left;
            free_node(old_node);
        } else {
            struct bst_node** pred = &(*node)->left;
        while ((*pred)->right != NULL) {
            pred = &(*pred)->right;
        }
        /* Swap values */
        void* temp = (*pred)->key;
        void* temp1 = (*pred)->data;
    
        (*pred)->data = (*node)->data;
        (*pred)->key = (*node)->key;
    
        (*node)->data = temp;
        (*node)->key = temp1;
    
        delete(pred);
        }
    }
    
    void visit(struct bst_node* node)
    {
        printf("%s\n", node->key);
    }
    
    void preorder_traverse(struct bst_node* root)
    {
        if (!root) return;
    
        visit(root);
        preorder_traverse(root->left);
        preorder_traverse(root->right);
    }
    
    void inorder_traverse(struct bst_node* root)
    {
        if (!root) return;
    
        inorder_traverse(root->left);
        visit(root);
        inorder_traverse(root->right);
    }
    
    void postorder_traverse(struct bst_node* root)
    {
            if (!root) return;
    
            postorder_traverse(root->left);
            postorder_traverse(root->right);
            visit(root);
    }
    
    void delete_tree(struct bst_node* root)
    {
        if (!root) return;
    
        delete_tree(root->left);
        delete_tree(root->right);
    
        free_node(root);
    }
    void*  ritorna_nodi(struct bst_node* root){
    
        if (!root) return;
    
        ritorna_nodi(root->left);    
        return root->data;  
        ritorna_nodi(root->right);      
    }
    void stm_aff(struct bst_node* root) // visita preorder quindi per ogni nodo visitato stampa la sua lista
    {
        if (!root) return;
    
        //stm_vst(root);
        stm_aff(root->left);
        stm_aff(root->right);
    }
    /*void stm_vst(struct bst_node* root) // dovrebbe ritornare una lista di accesori di quel nodo
    {
       return; 
    }*/
    
    #ifndef _BST_H_
    
    struct bst_node {
        char *key;
        void* data;
        struct bst_node* left;
        struct bst_node* right;
    };
    
    struct bst_node* new_node(char *key,void* data);
    
    void free_node(struct bst_node* node);
    typedef int my_comparator(void* left, void* right);
    
    
    
    struct bst_node** search(struct bst_node** root,char *key);
    void insert(struct bst_node** root,char *key, void* data);
    void delete(struct bst_node** node);
    void preorder_traverse(struct bst_node* root);
    void inorder_traverse(struct bst_node* root);
    void postorder_traverse(struct bst_node* root);
    void delete_tree(struct bst_node* root);
    
    #endif
    
    因此,我遇到问题的部分是main.c中的注释部分。如果您能提供任何帮助,我们将不胜感激

    m = (struct model_t*)((*node)->data); 
    

    您的
    search
    函数返回的
    struct bst\u节点**
    无法转换为
    struct model\u*
    。此函数的返回类型应该是
    struct model\u t*
    ,您应该
    Return(*node)->data我猜

    还请注意,没有理由将
    struct bst_node**
    传递给此函数。改为传递结构bst\U节点*
    。如果
    root
    被声明为
    struct bst\u node**
    则像这样调用函数:
    search(*root,mod),但我看不出它是双指针的任何原因,所以将其声明更改为
    struct bst_node*root以便通过简单的
    搜索(root,mod)调用函数

    您可以这样做:

    struct bst_node **r = search(root,mod);
    if(*r == NULL) {
    
      puts("Not found");
    
    } else {
    
      model_t *m = (*r)->data;
      if(m == NULL) {
         puts("Found, but data is NULL");
      } else {
         printf("\n--------%s\n",m->name);
      }
    
    }
    
    如果这不起作用(请详细解释事情是如何“不起作用的”),那么还有其他问题


    您还可以将search()函数更改为只返回一个bst_节点*,这里似乎不需要处理双指针

    摆脱强制转换空指针的需要?严重?
    (model*)搜索(root,mod)显然是错误的,您正在将
    struct bst\u节点**
    强制转换为
    model*
    。在第二种方法中,如果(node!=NULL&(*node)!=NULL)
    ,可能需要
    。方法2面临什么问题?@other.anon.coward search与search不同,因此它返回(*node)->data@another.anon.coward在方法2中,我在将数据分配给m,然后访问m字段时遇到问题。非常抱歉!史诗般的视觉失败:|。。。可能是添加时出错了。。。因为很长一段时间已经过去了,希望你已经解决了你的问题或者你有了一些指针,但是这意味着要修改bst容器的外部库,修改它的所有函数等等on@LucianEnache:我没有注意到它在外部图书馆里。现在检查我的答案。@Lucianneche如果外部库不清楚,也应该更改它。实际上,代码没有任何意义。它是一个双指针,因为我也使用该函数删除节点。。。正如我所说,这应该是一个处理泛型的库types@LucianEnache不要将同一个函数用于两个不同的目的。使用不同的功能。看来这种复杂性已经很难处理了。Kernighan的名言:
    “调试的难度是一开始编写代码的两倍。因此,如果你尽可能巧妙地编写代码,根据定义,你就没有足够的智慧来调试它。”
    它会给我另一个名字(总是相同的名字)如果我尝试访问其他属性,如price it Crash,那么可能其他地方出了问题。e、 g.内存损坏?构建BST时出现错误?我可以添加/删除节点而不会出错,因此我假设错误发生在我转换数据或smth时。@Lucian Enache否,如果您尝试上述代码,则不会。可能您没有为结构正确分配内存。可能是插入堆栈上声明的节点,可能是插入代码错误,或者是其他原因。@Lucian Enache您只分配了1个结构模型,而您一次又一次地插入相同的模型,这是行不通的。
    struct bst_node **r = search(root,mod);
    if(*r == NULL) {
    
      puts("Not found");
    
    } else {
    
      model_t *m = (*r)->data;
      if(m == NULL) {
         puts("Found, but data is NULL");
      } else {
         printf("\n--------%s\n",m->name);
      }
    
    }