【问题标题】:If the size of my stack is exceeded, how do I automatically adjust it? C++如果超出我的堆栈大小,我该如何自动调整它? C++
【发布时间】:2014-07-08 01:05:33
【问题描述】:

所以我有一个使用 LIFO(后进先出)方法的类 CStack。使用标准变量bottom/top/sizepush/pop/full/empty/print 等方法。这是一个char 堆栈。

我的问题是,如果我在这个堆栈中添加一些东西,当它已满时,我怎样才能自动调整大小?我想到了memcpy() 方法,但我还不太明白它是如何工作的。

任何帮助将不胜感激。

这是我的代码:

class CStack {
private:
    char *bottom_;
    char *top_;
    int size_;
public:

    CStack(int n = 20) {
        bottom_ = new char[n];
        top_ = bottom_;
        size_ = n;
    }

    void push(char c) {
        *top_ = c;
        top_++;
    }

    int num_items() {
        return (top_ - bottom_);
    }

    char pop() {
        top_--;
        return *top_;
    }

    int full() {
        return (num_items() >= size_);
    }

    int empty() {
        return (num_items() <= 0);
    }

    void print() {
        cout << "Stack currently holds " << num_items() << " items: ";
        for (char *element = bottom_; element < top_; element++) {
            cout << " " << *element;
        }
        cout << "\n";
    }

    ~CStack() { // stacks when exiting functions 
        delete [] bottom_;
    }
};

【问题讨论】:

  • 如果你想在内存中保持所有元素连续,你必须分配一个新的更大的数组,复制旧的,然后删除原来的。
  • 但请注意,您的代码不是惯用的 C++:new char[n] 创建了一个由 n 元素组成的数组,但您真正想要的是一个带有 empty 堆栈没有 元素。是时候将内存与对象分开了。
  • 所以我不能这样做?
  • @KerrekSB 没关系; vector.reserve() 做了类似的事情。
  • @MattMcNabb: reserve() 在不创建对象的情况下获取内存...从某种意义上说,详细研究std::vector&lt;int&gt; 可以教会您大约 95% 的 C++... :-)

标签: c++ automation stack stack-overflow stack-size


【解决方案1】:

这应该做你想做的事。它不处理异常,但我猜你的课程还没有走那么远?

void push(char c) {
    int used = top - bottom;
    if (used >= size_) {
        // grow the stack
        char* newBottom = new char[used + 20];
        memcpy(newBottom, bottom_, used * sizeof(char));
        top_ = newBottom + used;
        size_ = used + 20;
        delete[] bottom_;
        bottom_ = newBottom;        
    }
    *top_ = c;
    top_++;
}

【讨论】:

  • std::copy(bottom_, top_, newBottom); 优于 memcpy。除了允许编译器进行类型检查外,编译器更容易优化,如果 OP 扩展他的堆栈以存储带有构造函数的类型而不是 chars,它将继续工作。
  • 对于 OP:考虑当堆栈变大时会发生什么:ptrdiff_tused 的正确类型;这可能能够存储比int 更多的值。最好堆栈本身应该将大小存储为size_t,而不是存储top,因为size_t 可以具有比ptrdiff_t 更大的范围。最后,我们应该检查used+20 不会超出used 的范围。
  • @mattmcnab 当然可以,但是如果要使用 STL,那么整个类都是多余的,对吧?
  • 不一定,因为他可能想要与std::stack 不同的行为。如果“STL”是指std::copy,哈哈。 std::copystd::memcpy 是同一条船,这只是一个改进。
  • 我想通过这种格式和适合它的解决方案保持简单。我还没有使用矢量,但我想我可以研究一下。我刚开始学习 c++,有 Java 经验(学生级别)。无论如何,我会尝试这个,谢谢大家
猜你喜欢
  • 2017-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-24
  • 2015-12-29
  • 2017-12-27
  • 2020-12-06
  • 2019-09-04
相关资源
最近更新 更多