【问题标题】:What is the best way of implementing a dynamically resizing stack in C?在 C 中实现动态调整堆栈大小的最佳方法是什么?
【发布时间】:2011-01-04 09:59:17
【问题描述】:

在 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);
}

【问题讨论】:

  • 请发布一些代码。指针本身必须占用固定数量的内存来存储,无论它们指向什么。
  • 你所说的“最好”是什么意思?
  • 基本上有两种方式:1)使用增长数组,2)使用链表。什么对您最有效(或正确)取决于您的需要。

标签: c dynamic stack


【解决方案1】:

我认为问题在于您在通话中使用了错误的尺寸。您不想要指针的大小 - 您想要指针本身的大小。

【讨论】:

    【解决方案2】:

    一种方法是使用数组作为堆栈。跟踪阵列容量。如果数组已满,则分配一个新数组,将旧元素复制到新数组,然后删除旧数组。

    另一种选择是使用链表作为堆栈的基础。这允许对每个新元素进行动态分配。

    【讨论】:

      【解决方案3】:

      听起来你在做

      malloc(n * sizeof(void)) 
      

      直接或间接,你需要

      malloc(n * sizeof(void*))
      

      当然,真正的答案是 std::stack (c++)

      【讨论】:

      • 不,“真正的”答案是 java.util.Stack(在 Java 中)。或者更好的是 Lisp 列表。
      • 真正的答案是……练习!
      • C++ 从来都不是 C 问题的真正答案,除了“如果在 C 中附加两个加号会得到什么?”
      【解决方案4】:

      我以前回答过这个问题,作为上一个问题的子集:

      https://stackoverflow.com/questions/2006726/which-would-you-prefer-to-have-to-maintain/2007647#2007647

      您必须稍微调整一下——将 char* 替换为 void*,将“addString”重命名为“push”并编写一个“pop”函数。哦,对 malloc 和 realloc 的调用添加错误检查,因为在提问者的代码中省略了,所以在那个答案中省略了。

      正如尼尔所说,虽然“最好”是非常主观的。不断增长的数组只是实现堆栈的一种方式。根据使用模式以及您对代码复杂性、速度和内存使用的要求,您可能需要一个链表,或者您可能需要一个类似于 C++ 中的std::deque 类的混合列表/数组策略。

      【讨论】:

        【解决方案5】:

        使用C Interfaces and Implementations 中的Dave Hanson's code。这是一本很棒的书,您将了解如何使用动态数组技巧。优雅高效,高度可重用!代码可免费下载。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-11-27
          • 2010-10-30
          • 2013-08-10
          • 2011-06-03
          • 1970-01-01
          • 2021-10-11
          • 2015-09-07
          相关资源
          最近更新 更多