简体   繁体   English

这个简单的堆栈实现有什么问题

[英]What's wrong with this simple stack implementation

take a look at this naive (and just for training purpose) implementation of stack 看看这个朴素的(仅出于培训目的)堆栈的实现

#ifndef _STACK_H_
#define _STACK_H_
#include <algorithm>

template <typename T>
class Stack
{
    private:
        T* data_;
        size_t size_;
        size_t allocated_;
    public:
        Stack() : data_(new T[10]),size_(0),allocated_(10) {}
        ~Stack() 
        { 
            delete[] data_; 
        }
        size_t size() const { return size_; }
        T top() const
        {
            if (size_ == 0)
                throw "Error the Stack is Empty";
            return data_[size_]; 
        }

        void pop() 
        { 
            if (size_ == 0) 
                throw "Error the Stack is Empty";
            else
                --size_;
        }

        void push(T toAdd)
        {
            if (size_ < allocated_)
                data_[++size_] = toAdd;
            else
            {
                T* newData = new T[allocated_*2];
                std::copy(data_,data_ + size_,newData);
                delete[] data_;
                data_ = newData;
                ++size_;
                allocated_ = allocated_*2;
            }
        }

        size_t capacity() const { return allocated_; }
};

#endif

Then If I use it in my test application: 然后,如果我在测试应用程序中使用它:

#include <iostream>
#include "Stack.h"
using std::endl;
using std::cout;

int main(int argc,char* argv[])
{
    Stack<int> myStack;

    cout << myStack.size() << " it should be 0" << endl;
    cout << myStack.capacity() << " it should be 10" << endl;
    try 
    {
        cout << myStack.top() << " it should be 40" << endl;
    }
    catch(...)
    {
        cout << "Error the stack is empty" << endl;
    }

    myStack.push(10);
    myStack.push(20);
    myStack.push(30);
    myStack.push(40);

    cout << myStack.size() << " it should be 4" << endl;
    cout << myStack.capacity() << " it should be 10" << endl;
    cout << myStack.top() << " it should be 40" << endl;
    myStack.push(50);
    myStack.push(60);
    myStack.push(70);
    myStack.push(80);
    myStack.push(90);
    myStack.push(100);
    myStack.push(110);
    myStack.push(120);

    cout << myStack.size() << " it should be 12" << endl;
    cout << myStack.capacity() << " it should be 20" << endl;
    cout << myStack.top() << " it should be 120" << endl;

    myStack.push(50);
    myStack.push(60);
    myStack.push(70);
    myStack.push(80);
    myStack.push(90);
    myStack.push(100);
    myStack.push(110);
    myStack.push(120);
    myStack.push(210);
    myStack.push(220);

    cout << myStack.size() << " it should be 22" << endl;
    cout << myStack.capacity() << " it should be 40" << endl;
    cout << myStack.top() << " it should be 220" << endl;

    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();  
    myStack.pop();
    myStack.pop();
    myStack.pop();

    cout << myStack.size() << " it should be 9" << endl;
    cout << myStack.capacity() << " it should be 20" << endl;
    cout << myStack.top() << " it should be 90" << endl;

    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();
    myStack.pop();

    cout << myStack.size() << " it should be 0" << endl;
    cout << myStack.capacity() << " it should be 40" << endl;

    try 
    {
        myStack.top();
    }
    catch(...)
    {
        cout << "Error the stack is empty" << endl;
    }

    try 
    {
        myStack.pop();
    }
    catch(...)
    {
        cout << "Error the stack is empty" << endl;
    }

    return 0;
}

I got this error: 我收到此错误:

0 it should be 0
10 it should be 10
Error the stack is empty
4 it should be 4
10 it should be 10
40 it should be 40
12 it should be 12
20 it should be 20
120 it should be 120
22 it should be 22
40 it should be 40
220 it should be 220
9 it should be 9
40 it should be 20
90 it should be 90
0 it should be 0
40 it should be 40
*** glibc detected *** /home/alessandro/Projects/testStack/testStack/bin/Debug/testStack: malloc(): memory corruption (fast): 0x0000000000871040 ***
======= Backtrace: =========
/lib/libc.so.6(+0x775b6)[0x7f6c49c395b6]
/lib/libc.so.6(+0x7b8e9)[0x7f6c49c3d8e9]
/lib/libc.so.6(__libc_malloc+0x6e)[0x7f6c49c3e58e]
/usr/lib/libstdc++.so.6(__cxa_allocate_exception+0x17)[0x7f6c4a4a87d7]
/home/alessandro/Projects/testStack/testStack/bin/Debug/testStack[0x401471]
/home/alessandro/Projects/testStack/testStack/bin/Debug/testStack[0x4012ac]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f6c49be0c4d]
/home/alessandro/Projects/testStack/testStack/bin/Debug/testStack[0x400ba9]
======= Memory map: ========
00400000-00402000 r-xp 00000000 08:05 13107397                           /home/alessandro/Projects/testStack/testStack/bin/Debug/testStack
00601000-00602000 r--p 00001000 08:05 13107397                           /home/alessandro/Projects/testStack/testStack/bin/Debug/testStack
00602000-00603000 rw-p 00002000 08:05 13107397                           /home/alessandro/Projects/testStack/testStack/bin/Debug/testStack
00871000-00892000 rw-p 00000000 00:00 0                                  [heap]
7f6c44000000-7f6c44021000 rw-p 00000000 00:00 0 
7f6c44021000-7f6c48000000 ---p 00000000 00:00 0 
7f6c49bc2000-7f6c49d3c000 r-xp 00000000 08:05 13500726                   /lib/libc-2.11.1.so
7f6c49d3c000-7f6c49f3b000 ---p 0017a000 08:05 13500726                   /lib/libc-2.11.1.so
7f6c49f3b000-7f6c49f3f000 r--p 00179000 08:05 13500726                   /lib/libc-2.11.1.so
7f6c49f3f000-7f6c49f40000 rw-p 0017d000 08:05 13500726                   /lib/libc-2.11.1.so
7f6c49f40000-7f6c49f45000 rw-p 00000000 00:00 0 
7f6c49f45000-7f6c49f5b000 r-xp 00000000 08:05 13500495                   /lib/libgcc_s.so.1
7f6c49f5b000-7f6c4a15a000 ---p 00016000 08:05 13500495                   /lib/libgcc_s.so.1
7f6c4a15a000-7f6c4a15b000 r--p 00015000 08:05 13500495                   /lib/libgcc_s.so.1
7f6c4a15b000-7f6c4a15c000 rw-p 00016000 08:05 13500495                   /lib/libgcc_s.so.1
7f6c4a15c000-7f6c4a1de000 r-xp 00000000 08:05 13500730                   /lib/libm-2.11.1.so
7f6c4a1de000-7f6c4a3dd000 ---p 00082000 08:05 13500730                   /lib/libm-2.11.1.so
7f6c4a3dd000-7f6c4a3de000 r--p 00081000 08:05 13500730                   /lib/libm-2.11.1.so
7f6c4a3de000-7f6c4a3df000 rw-p 00082000 08:05 13500730                   /lib/libm-2.11.1.so
7f6c4a3df000-7f6c4a4d5000 r-xp 00000000 08:05 9834159                    /usr/lib/libstdc++.so.6.0.13
7f6c4a4d5000-7f6c4a6d5000 ---p 000f6000 08:05 9834159                    /usr/lib/libstdc++.so.6.0.13
7f6c4a6d5000-7f6c4a6dc000 r--p 000f6000 08:05 9834159                    /usr/lib/libstdc++.so.6.0.13
7f6c4a6dc000-7f6c4a6de000 rw-p 000fd000 08:05 9834159                    /usr/lib/libstdc++.so.6.0.13
7f6c4a6de000-7f6c4a6f3000 rw-p 00000000 00:00 0 
7f6c4a6f3000-7f6c4a713000 r-xp 00000000 08:05 13500723                   /lib/ld-2.11.1.so
7f6c4a8e5000-7f6c4a8e9000 rw-p 00000000 00:00 0 
7f6c4a90f000-7f6c4a912000 rw-p 00000000 00:00 0 
7f6c4a912000-7f6c4a913000 r--p 0001f000 08:05 13500723                   /lib/ld-2.11.1.so
7f6c4a913000-7f6c4a914000 rw-p 00020000 08:05 13500723                   /lib/ld-2.11.1.so
7f6c4a914000-7f6c4a915000 rw-p 00000000 00:00 0 
7fffdbc1e000-7fffdbc33000 rw-p 00000000 00:00 0                          [stack]
7fffdbc7b000-7fffdbc7c000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
The application was terminated by a signal: SIGABRT

The weird thing is that if I replace Stack<int> with Stack<double> or Stack<char> the error disappear! 奇怪的是,如果我将Stack<int>替换为Stack<double>Stack<char> ,错误将消失! I am using g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3. 我正在使用g ++(Ubuntu 4.4.3-4ubuntu5)4.4.3。

I cannot spot the error in Stack,do you have any ideas? 我无法在Stack中发现错误,您有任何想法吗?

The problem is in your push . 问题出在你的push It should be: 它应该是:

if (size_ < allocated_)
    data_[size_++] = toAdd;
//            ^^^^^^^

Also, top should return data_[size_-1] 另外, top应该返回data_[size_-1]


Explanation - the first fix - at the beginning, size_==0 and when you do data_[++size_] you write directly at the second element, with index 1 (not the prefix operator++ ). 说明-第一个解决方法-首先是size_==0并且当您执行data_[++size_]您直接在第二个元素上写了索引1(而不是前缀 operator++ )。

The second fix - similar error - all indexes start from 0 to n, non-inclusive. 第二个解决方案-类似错误-所有索引均从0到n(不包括在内)开始。 So your range is [0, n), that's why you should return the element with index, size_-1 所以您的范围是[0,n),这就是为什么您应该返回索引为size_-1的元素的原因

EDIT : Argh, right, you're missing to add the new element in the else of your push member function. 编辑 :Argh,对,您缺少在push成员函数的else中添加新元素的功能。

In your Top function, it should be return data_[size_ - 1]; 在您的Top函数中,它应该是return data_ [size_-1];

The push function seems wrong too, when you reallocate your buffer, you don't write the value to push in it. push函数也似乎是错误的,当您重新分配缓冲区时,您不会写入要推送的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM