2

我想在我的应用程序中创建一个全局堆栈,并将某些对象放在这个堆栈上。这些对象不是固定大小的。

我目前有;

static char contextStack[CONTEXT_MAX_SIZE];
static char *top = &contextStack[0];

我重写了new继承的基类的运算符

static void *operator new(size_t size) {
  void *Result;
  Result = top;
  top = top + size;
  return Result;
};

问题是我将如何实现delete运算符以将其从堆栈中弹出?它没有告诉我物品有多大?我是否必须将每个条目的大小存储在数组中?

(ps) 最后创建的总是最先被删除的。并符合堆栈。

4

4 回答 4

2

我是否必须将每个条目的大小存储在数组中?

您可以使用单独的存储区域,也可以使用malloc实现经常遵循的策略:它们将大小存储在它们返回给您的指针前面的已知位置。当您调用 时free,它们会检查您传入的指针之前的位置,从那里获取大小,然后继续释放。

在您的情况下,您可以在块本身之后立即推送块的大小。到了出栈的时候,先出栈大小,再出栈数据块。

使用堆栈时需要注意的一件事是数据对齐:根据架构,将多字节类型存储在奇数偏移量(不能被四、八等分的偏移量)可能会导致性能下降或总线错误。您需要检查您的平台细节,看看是否需要在推入堆栈的连续元素之间引入额外的“填充”。

于 2012-07-08T11:33:12.130 回答
1

在这种情况下,有不同的选项来处理内存。如果您以递增的顺序返回内存(似乎是这种情况),则不需要记住大小。最后分配的内存块将从分配的指针指向top 您甚至不需要执行算术运算,因为将 top 设置为传递给的指针delete就足够了。

如果您按降序分配内存(这在堆栈中很常见),您可以将大小存储在堆栈本身中。执行指针运算以获得 new Result( top - requested_size),然后递减sizeof(int),将大小存储在那里并将指针设置top为该指针。

您应该了解平台中的对齐限制,即使平台允许对所有数据类型进行非对齐访问,出于性能(和线程安全)原因,您可能仍希望对齐数据。

于 2012-07-08T11:40:34.607 回答
1

如果您使用模板类来创建堆栈,则无需知道每个项目的大小,这会容易得多。

于 2012-07-08T12:03:44.600 回答
0

从我在处理堆栈时使用 Assembly 的经验来看:当代码想要从堆栈中弹出一些东西时,该代码负责知道该东西有多大或预期有多大。堆栈只是连续的一大块数据,从技术上讲,只要有那么多数据,您就可以从技术上取出任意大的数据块。

所以你的代码需要提前知道对象有多大(你似乎没有的信息)。当然,您可以通过任何其他方式实现您的“堆栈”,包括您建议将大小存储在数组中。这样做会使堆栈的简单性进一步复杂化,但在您的实现中可能是必需的。

于 2012-07-08T11:32:26.217 回答