在 C 中用 void 指针存储整数的最佳方法是什么?

What is the best way to store integers with void pointers in C?

你好,我正在尝试学习和构建 C 中的数据结构,我想在堆栈中逐步存储整数。 我的结构是这样的:

typedef struct STACK_NODE_s *STACK_NODE;
typedef struct STACK_NODE_s{
    STACK_NODE forward;
    void *storage;
} STACK_NODE_t;

typedef struct L_STACK_s{
    STACK_NODE top;
} L_STACK_t, *L_STACK;

在 while 循环中,我想以整数形式读取和存储我的字符。

//assume that str is an proper string
//assume that we have a linked stack called LS
int i=0;
int temp;
while(str[i]!='[=11=]'){
    tmp=str[i]-'0';
    push(LS,(void *)&tmp);
}

我知道这不会正常工作,因为我们一遍又一遍地存储同一个变量的地址。 我是否需要分配一个辅助数组以便将它们 1 对 1 存储,或者有更好的方法吗?

我像预期的那样使用辅助数组解决了这个问题。如果有人提出更好的解决方案,我们非常欢迎。

答案必须针对您问题的两个不同方面: 如何组织一些项目集合,以及从哪里获取内存来执行此操作。

第一个代码片段/链表格式

第一个代码片段就这样很好。 它设置了一个 linked list, which has its pros and cons, but serves very well if you don't know the number of items in advance, if you want to be able to quickly remove or insert items somewhere in the middle of the list, and if you don't mind that looking up one certain entry inside the list costs you O(N) effort.

For a generic library-like implementation...

... void* 与 ANSI C 一样好。 例如,在 C++ 中,您可以制作一个模板,使存储在列表中的类型保持打开状态(或者更好的是,您可以直接重用 class forward_list<int> 中众所周知的 STL 实现)。 遗憾的是,ANSI C 没有可比的东西。 一种解决方案是您选择的那个,创建 int 个对象并将它们的地址挂接到您的 void* 列表中。 泛型库实现的另一种解决方案是为类型使用预编译器宏,并在包含泛型实现的头文件上方定义此宏。这试图类似于干净的 C++ 解决方案,但是使用预编译器它不是类型安全的,因此这种方法远非美观并且存在一些风险。

第二个代码片段/内存分配

使用 void* 而不是 int (或任何非指针类型)创建列表需要您在列表旁边分配更多内存。 也就是说,您不仅必须分配每个列表项(= STACK_NODE_t 类型的变量),而且还必须分配实际的条目值(例如,*(int*)(LS->storage))。

这意味着您必须 allocate/deallocate 以其他比堆栈更持久的方式处理数据。 在大多数系统上,您可以为此使用 malloc/free,并且您只需要考虑 malloc 可用的堆大小和 de-/allocating 所花费的时间. 如果列表要实现实时性要求或者在嵌入式系统上,你可能没有malloc或者你可能不被允许使用它。 然后你必须为你的列表分配和实现你自己的堆(= storage 项的内存池)。 如何实现这样一个具有所需属性的内存池是一个单独的问题,我们会走到这里。

在任何情况下,您都不能使用指向堆栈变量的指针(如函数内的局部变量),因为一旦函数退出,该变量的内存"behind"将不会为此目的保留,并且内存可能同时用于不同的事情。 然而,这显然是第二个代码片段所做的。 正如您自己注意到的那样,走这条路...

we store the same variable's adress over and over again.

为同一列表的另一个条目重复使用内存位置是上述风险的极端情况。