Search code examples
cvoid-pointers

How to make an instance in runtime, C


I need to create an instance of one of several data structures(for example: DynamicArray, BST, HashMap, Trie) on C language. The name of data structure read from file and then instance of data type must be create; In general, i need to develop polymorphism but i don't know how to create an instance of structure in runtime; I know there's a solving with void-pointer function but i don't know how...

ATTENTION: I need to create an application, that read file. There's a 6 variants of queues(binary heap, binomial heap, leftist heap, skew heap, fibonacci heap and Treap) and 4 variants(Vector, HashMap, Trie, BST) of containers for this queue. And if i don't develop a sort of polymorphism, then i need to work with 24 difference case because data in source file generate accidentally. Example test file:

LeftistHeap - queue
Trie - container
06:18:39 03/05/24 - time start
06:28:39 03/05/24 - time finish
42 - min time for 1 request 
53 - max time for 1 request 
14 - number of departments
15 25 44 47 48 39 38 32 37 28 11 45 27 11 - count for each department 

I try to use Generic for this problem, but it didn't solve my problem;

There's compilation error:

void error: ‘_Generic’ selector of type ‘void’ is not compatible with any association

void vec() {
    printf("Vector\n");
}

void bst() {
    printf("bst\n");
}

void ht() {
    printf("Ht\n");
}

#define TEST_FUNC(X) _Generic((X), \
    Vector: vec, \
    BST: bst, \
    Hash_Table: ht \
)    

int main()
{
    char* in = "Vector";

    void* data = NULL;
    
    if (strcmp(in, "Vector") == 0) {
 
        data = (Vector*)malloc(sizeof(Vector));
    } else if (strcmp(in, "BST") == 0) {
        data = (BST*)malloc(sizeof(BST));
    } 

    TEST_FUNC(*data); 
} 

Solution

  • _Generic((X) macro is used during compilation not at the run time. So you can't use it in your case. And remember: the cast when you assign to void * pointer, that cast doe not convert it to another type of pointer.

    You need to do it runtime. Example:

    typedef struct
    {
        int dummy[5];
    }BST;
    
    typedef struct
    {
        int dummy[15];
    }VECTOR;
    
    typedef struct
    {
        int dummy[25];
    }HT;
    
    void vec(VECTOR *v) {
        printf("Vector\n");
    }
    
    void bst(BST *bst) {
        printf("bst\n");
    }
    
    void ht(HT *ht) {
        printf("Ht\n");
    }
    
    typedef enum
    {
        BST_T,
        VECTOR_T,
        HT_T,
        UNKNOWN_T,
    }type_t;
    
    void TEST_FUNC(void *data, const type_t type)
    {
        switch(type)
        {
            case VECTOR_T:
                vec(data);
                break;
            case BST_T:
                bst(data);
                break;
            case HT_T:
                ht(data);
                break;
            default:
                printf("Unknown type\n");
                break;
        }
    }
    
    
    int main()
    {
        char* in = "Vector";
        size_t size = 0;
        type_t type = UNKNOWN_T;
        void *data = NULL;
        
        if (!strcmp(in, "Vector")) { size = sizeof(VECTOR); type = VECTOR_T;}
        else if (!strcmp(in, "HT")) { size = sizeof(HT); type = HT_T;}
        else if (!strcmp(in, "BST")) { size = sizeof(BST); type = BST_T;}
     
        if(size) data = malloc(size);
    
        TEST_FUNC(data, type); 
    }