测试Doom 3 Stack实现时损坏的堆栈

时间:2013-09-19 17:42:57

标签: c++ memory stack allocation

我得到了

  

变量'a'周围的堆栈已损坏。

尝试此代码时:

    #include "Stack.h"
    #include <iostream>

    struct product {
        int weight;
        float price;
    } ;

    void main(void){
        product a = {1, 4.0f};
        product b = {2, 5.0f};
        product c = {3, 6.0f};

        idStackTemplate<product, sizeof(product)> stack;

        stack.Add(&a);
        stack.Add(&b);
        stack.Add(&c);

        product * first, * second, *third;

        third = stack.Get();
        second = stack.Get();
        first = stack.Get();

        std::cout << first->price << "\t" << first->weight << "\n";
        std::cout << second->price << "\t" << second->weight << "\n";
        std::cout << third->price << "\t" << third->weight << "\n";
    }

Stack.h源代码位于here

否则代码会打印出正确的值。

我是c / c ++的初学者/中级人员,所以请你帮我理解idStack是如何工作的以及我做错了什么。

我尝试使用idStack(type,next)宏创建堆栈对象 - 据我所知,你应该将产品的一个元素放入“next”参数,以便计算偏移量。它从来没有正常工作(重量或价格)虽然我没有得到任何堆栈损坏错误但变量没有正确打印出来。

我还看到Doom 3源代码中的一些代码使用了内存池的动态分配,这有点可以解释这一点,但我看不到这种技术在这里使用...

编辑:我觉得我应该在堆上(3 * sizeof(a))使用自定义分配器分配足够的内存,然后在新分配的内存的开头初始化a。我倾向于正确的方向吗?

1 个答案:

答案 0 :(得分:2)

这个堆栈实现是侵入性的 - 它期望有一个指针可供堆栈模板使用。在这种情况下,第二个模板参数旨在具有该指针的偏移量 - 而不是要存储的对象的大小。

因此,您可以进行以下修改:

struct product {
    int weight;
    float price;
    struct product* next;   // <-- link pointer field
} ;


// the stack declaration:

idStackTemplate<product, offsetof(struct product, next)> stack;
//                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

不言而喻,这种容器通常不被视为良好做法。