在C中实现动态调整大小的堆栈的最佳 正确方式是什么?
例如,我想为堆栈分配一定量的内存,但是当该堆栈满了时,分配的内存会加倍以容纳新数据等。
我有一个使用简单的void指针数组实现的堆栈,这样我可以存储所有类型的指针,因此它非常可重用。当我尝试使用malloc()/ realloc()实现这个时,由于没有指定大小的void指针,我在执行指针数学时遇到错误。
在C中实现动态可调整大小的堆栈的最佳 正确方式是什么?
修改
我正在尝试类似这样的代码(删除了错误检查)但我现在明白我无法与这样的void指针进行交互。所以我只是想一想如何合法地做这样的事情。这对我来说是一次很大的学习练习,因为我从未真正接触过C。
#include <stdio.h>
#include <stdlib.h>
#include "stack.h"
static int index = 0;
void* CreateStack(void)
{
void *stack = malloc(INITIAL_STACK_SIZE);
return stack;
}
void* Pop(void *stack)
{
return stack + index--;
}
void Push(void *stack, void *value)
{
*(stack + index) = value;
}
void FreeStack(void *stack)
{
free(stack);
}
答案 0 :(得分:4)
我认为问题是您在通话中使用了错误的尺寸。你不想要指针的大小 - 你想要指针本身的大小。
答案 1 :(得分:3)
听起来像你在做什么
malloc(n * sizeof(void))
直接或间接,你需要
malloc(n * sizeof(void*))
当然真正的答案是std :: stack(在c ++中)
答案 2 :(得分:1)
一种方法是使用数组作为堆栈。跟踪阵列容量。如果数组变满,则分配一个新数组,将旧元素复制到新数组,然后删除旧数组。
另一种选择是使用链表作为堆栈的基础。这允许在每个新元素上进行动态分配。
答案 3 :(得分:1)
之前我已经回答了这个问题,作为上一个问题的一个子集:
您必须稍微调整一下 - 将void *替换为void *,将“addString”重命名为“push”并编写“pop”函数。哦,并在对malloc和realloc的调用上添加错误检查,在该答案中省略了,因为在提问者的代码中省略了它。
像尼尔说的那样,虽然“最好”是非常主观的。不断增长的数组只是实现堆栈的一种方式。根据使用模式以及您对代码复杂性,速度和内存使用的要求,您可能需要链表,或者您可能需要类似于C ++中std::deque
类的混合列表/数组策略。
答案 4 :(得分:0)
使用Dave Hanson's code中的C Interfaces and Implementations。这是一本很棒的书,你会看到如何做动态数组技巧。优雅高效,高度可重复使用!该代码可免费下载。