0

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); 
} 
8
  • 1
    You can't dereference a void * pointer. It doesn't have a type. Commented Mar 8, 2024 at 20:49
  • @Someprogrammerdude, i know, read my question, please Commented Mar 8, 2024 at 20:51
  • 3
    C doesn't have run-time type information. So there's no way for _Generic to know which structure type data points to. It uses the declared type of X, not its actual type. Commented Mar 8, 2024 at 21:04
  • 1
    I think that if you need to map strings to data types, you'll need to write code to take a string such as HashMap and return a structure with the appropriate information about how to use that type. And "appropriate information" is where the trouble starts. Will it be the same structure for all types, or will different types have different descriptive structures? Commented Mar 8, 2024 at 21:06
  • 1
    These casts on malloc() serve no useful purpose here, especially when assigning to void*. You don't need to cast malloc() in C. Commented Mar 8, 2024 at 21:27

1 Answer 1

1

_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); 
}
Sign up to request clarification or add additional context in comments.

1 Comment

I am really grateful to you! This is exactly the thing I was looking for, thanks again.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.