C 是否可以构建一个足够通用的队列,允许它将任何数据类型存储为对象?

C 是否可以构建一个足够通用的队列,允许它将任何数据类型存储为对象?,c,pointers,void-pointers,C,Pointers,Void Pointers,本质上,我试图实现的是一个通用的enqueue(Queue*Queue,void*key)函数。我希望此队列存储任何数据类型。以下是我构建队列的方式: typedef struct Node { void *key; struct Node *next; }Node; typedef struct Queue { Node *front; Node *back; }Queue; Queue* initializeQueue() { Queue *que

本质上,我试图实现的是一个通用的
enqueue(Queue*Queue,void*key)
函数。我希望此队列存储任何数据类型。以下是我构建队列的方式:

typedef struct Node {
    void *key;
    struct Node *next;
}Node;

typedef struct Queue {
    Node *front;
    Node *back;
}Queue;

Queue* initializeQueue() {
    Queue *queue = (Queue*) malloc(sizeof(Queue));
    queue->front = NULL;
    queue->back = NULL;
    return queue;
}

void enqueue( Queue *queue, void *key ) {
    Node *tempRef = (Node*) malloc(sizeof(Node)); // Inserted Node will be in the back of Queue
    tempRef->key = key;
    tempRef->next = NULL;
    if ( queue->front == NULL && queue->back == NULL ){ // When the Queue is empty
        queue->front = tempRef;
        queue->back = tempRef;
    }
    else { // When the Queue is non-empty
        queue->back->next = tempRef; 
        queue->back = tempRef;
    }
}
但事实是,这个实现是错误的,因为我将参数void指针存储为一个对象,它指向的地址依赖于外部数据类型(例如,像char),而这不是预期的。例如,以下代码将地址和密钥链接到队列中的对象:

char key = '-';
enqueue(queue, &key );
因此,理想情况下,我希望在队列中存储不是地址的对象。但是,如何在节点结构中将任意数据类型存储为对象?显然,利用
void*
并不是一个解决方案,正如我在上面所说的,那么,是否有可能找到解决我问题的方法呢

提前谢谢

是否可以构建一个足够通用的队列,允许它将任何数据类型存储为对象

考虑一下
fwrite()
如何知道如何编写任何对象的内容:
通过接收对象的地址和大小

节点
需要保存对象副本的地址及其大小

typedef struct Node {
    struct Node *next;
    // void *key;
    void *data;
    size_t size;
} Node;
enqueue()
需要展开

// void enqueue( Queue *queue, void *key )
void enqueue(Queue *queue, const void *data, size_t size)
// Address of the object --------------^^^^
// Size of the object ------------------------------^^^^
。。。然后为副本分配空间,然后复制它

Node *tempRef = malloc(sizeof *tempRef);
tempRef->data = malloc(size);
if (tempRef->data == NULL) {
  free(tempRef);
  return true; // fail
}
memcpy(tempRef->data, data, size);
tempRef->size = size;
tempRef->next = NULL;
...
return false; // success
如果对象中有指针…

只复制指针,不复制指针指向的数据

但此时类型已丢失

数据已存储,但类型已丢失

在解排队时,可用的只是排队数据的地址和大小,而不是其类型

解队列可以假定类型-如果此代码具有一组用于该类型的包装函数,那么这就足够了

。。。或者

还可以通过某种枚举保存类型(来自一组有限的类型)。研究
\u通用


如果类型在整个队列中相同或每个节点可能不同,则会出现代码简化/复杂性


祝你好运。

为什么不直接使用
排队(queue,“-”
?字符串文字衰减为字符指针,而字符指针隐式转换为空指针。或者还有其他一些用例没有涵盖?在回答这个问题之前,还有一些其他问题需要解决:队列是存储传递给它的指针,还是复制对象?如果是指针,您将如何确保被引用对象的寿命足够长,以便以后仍然可用?如果是对象,队列如何知道要复制多少字节?在任何一种情况下,当你把条目从队列中拿出来时,你怎么知道它是什么类型的呢?我觉得这就是所谓的“XY问题”。你问的是如何实现一个特定的(可能是非常糟糕的)解决问题的方法,而不是后退一步,而是问如何实现底层问题。为了回答所问的非常具体的问题,避免声明一个单独的变量,你可以使用数组类型,例如,
enqueue(queue,(int[1]){42});
将传递一个指向临时
int
的指针,该指针由42初始化。但是这个临时变量将不再存在于块的末尾,就像局部变量一样,因此您最好在该块末尾创建一个副本或将其从队列中删除,否则您将有一个悬空的指针。@UlrichEckhardt这是一个XY问题,非常感谢您指出这一点。多亏了你,我才知道这个新的沟通和逻辑问题