C++ 最小C++;STL向量实现问题

C++ 最小C++;STL向量实现问题,c++,stl,vector,g++,segmentation-fault,C++,Stl,Vector,G++,Segmentation Fault,我有一个技术问题,这让我很困惑。我提前道歉,因为我可能没有提供相关细节;我还不知道为什么会出错,如果包含我正在使用的所有代码,那就太过分了 我正在使用一个大型的程序,使用C++ STL。我正在将这段代码移动到一个非常敏感的环境中,没有标准的clib或STL实现;它将重新定义malloc/free/new/delete等。。。为此,我需要用自己的简化实现替换std::parts。我从std::vector开始。现在它在标准的生态系统中运行,所以它是GNULIBC和STL。唯一改变的是这个向量类 当

我有一个技术问题,这让我很困惑。我提前道歉,因为我可能没有提供相关细节;我还不知道为什么会出错,如果包含我正在使用的所有代码,那就太过分了

我正在使用一个大型的程序,使用C++ STL。我正在将这段代码移动到一个非常敏感的环境中,没有标准的clib或STL实现;它将重新定义malloc/free/new/delete等。。。为此,我需要用自己的简化实现替换std::parts。我从std::vector开始。现在它在标准的生态系统中运行,所以它是GNULIBC和STL。唯一改变的是这个向量类

当我用替换的类执行程序时,它会出现故障。我已经通过GDB实现了这一点,并发现程序将使用下标操作符从向量请求一个对象。当返回对象引用时,将调用一个方法,并且程序将发生故障。它似乎找不到这个方法,最终在GDB的main_arena()中结束。对象的类型是继承的类

我真的一点也不确定这里有什么问题。我很想提供更多的细节,但我不确定我还能提供什么。我只能假设我的向量实现出了问题,因为程序中的其他内容没有改变。也许有一些明显的我做错了的事情我根本没有看到

我使用的是:g++(GCC)4.4.5 20110214(Red Hat 4.4.5-6)

我非常感谢任何反馈/建议

#ifndef _MYSTL_VECTOR_H_
#define _MYSTL_VECTOR_H_

#include <stdlib.h>
#include <assert.h>

typedef unsigned int uint;

namespace mystl
{
    /******************
      VECTOR
    ********************/


    template <typename T>
    class vector 
    {

        private:

            uint _size;
            uint _reserved;
            T *storage;

            void init_vector(uint reserve)
            {
                if (reserve == 0)
                {
                    _reserved = 0;
                    return;
                }

                storage = (T*)malloc(sizeof(T)*reserve);
                assert(storage);

                _reserved = reserve;
            }

        public:
            vector()
            {
                    // std::cerr << "default constructor " << this << std::endl;
                    storage = NULL;
                    _size = 0;
                    _reserved = 0;
            }

            vector(const vector<T> &other)
            {
                // std::cerr << "copy constructor " << this << std::endl;

                storage = NULL;
                _size = 0;
                _reserved = 0;


                init_vector(other.size());
                _size = other.size();

                for (uint i=0; i<other.size(); i++)
                {
                    storage[i] = T(other[i]);
                }
            }

            vector(uint init_num, const T& init_value)
            {
                    // std::cerr << "special constructor1 " << this << std::endl;

                        storage = NULL;
                        _size = 0;
                        _reserved = 0;

                      init_vector(init_num);

                      for (size_t i=0; i<init_num; i++)
                      {
                          push_back(init_value);
                      }
            }

            vector(uint init_num)
            {
                    // std::cerr << "special constructor2 " << this << std::endl;

                        storage = NULL;
                        _size = 0;
                        _reserved = 0;

                      init_vector(init_num);
            }

            void reserve(uint new_size) 
            {   
                if (new_size > _reserved) 
                {

                    storage = (T*)realloc(storage, sizeof(T)*new_size);
                    assert(storage);

                    _reserved = new_size;
                }
            }

            void push_back(const T &item) 
            {
                if (_size >= _reserved) 
                {
                    if (_reserved == 0) _reserved=1;
                    reserve(_reserved*2);
                }

                storage[_size] = T(item);
                _size++;
            }

            uint size() const
            {
                return _size;
            }

            ~vector()
            {
                if (_reserved)
                {
                    free(storage);
                    storage = NULL;
                    _reserved = 0;
                    _size = 0;
                }
            }

            // this is for read only
            const T& operator[] (unsigned i) const
            {
                // do bounds check...
                if (i >= _size || i < 0)
                {
                    assert(false);
                }
                return storage[i];
            }


            T& operator[] (unsigned i)
            {
                // do bounds check...
                if (i >= _size || i < 0)
                {
                    assert(false);
                }
                return storage[i];
            }

            // overload = operator
            const vector<T>& operator= (const vector<T>& x)
            {
                // check for self
                if (this != &x)
                {   
                    _reserved = 0;
                    _size = 0;
                    storage = NULL;

                    init_vector( x.size() );

                    for(uint i=0; i<x.size(); i++)
                    {
                        storage[i] = T(x[i]);
                    }

                    _size = x.size();
                }

                return *this;
            }

            uint begin() const
            {
                return 0;
            }

            void insert(uint pos, const T& value)
            {
                push_back(value);
                if (size() == 1)
                {
                          return;
                }
                for (size_t i=size()-2; i>=pos&& i>=0 ; i--)
                {
                    storage[i+1] = storage[i];
                }
                storage[pos] = value;
            }

            void erase(uint erase_index)
            {
                if (erase_index >= _size) 
                {
                    return;
                }
                //scoot everyone down by one
                for (uint i=erase_index; i<_size; i++)
                {
                    storage[i] = storage[i+1];
                }
                _size--;
            }


            void erase(uint start, uint end)
            {

                if (start > end)
                {
                    assert(false);
                }

                if (end > _size)
                    end = _size;

                for (uint i=start; i<end; i++)
                {
                    erase(start);
                }

                assert(false);
            }

            void clear()
            {
                erase(0,_size);
            }

        bool empty() const
        {
            return _size == 0;
        }

    }; //class vector
}


#endif // _MYSTL_VECTOR_H_
\ifndef\u MYSTL\u VECTOR\u H_
#定义_MYSTL_VECTOR_H_
#包括
#包括
typedef无符号整数单元;
名称空间mystl
{
/******************
矢量
********************/
模板
类向量
{
私人:
单位尺寸;
uint_保留;
T*储存;
无效初始向量(单位保留)
{
如果(保留==0)
{
_保留=0;
返回;
}
储存量=(T*)马洛克(sizeof(T)*储量);
断言(存储);
_保留=保留;
}
公众:
向量()
{
//哇

  • 赋值运算符也会泄漏内存

  • 因为您使用的是malloc/release,所以类型T的构造函数将不会被调用,因此除了最琐碎的对象之外,您不能将向量用于任何事情

  • 编辑: 今天早上我有点无聊:试试这个

    #include <stdlib.h> // For NULL
    #include <new>      // Because you need placement new
    
    // Because you are avoiding std::
    // An implementation of swap
    template<typename T>
    void swap(T& lhs,T& rhs)
    {
        T   tmp = lhs;
        lhs = rhs;
        rhs = tmp;
    }
    
    
    template <typename T>
    class vector
    {
        private:
            unsigned int dataSize;
            unsigned int reserved;
            T*           data;
    
        public:
            ~vector()
            {
                for(unsigned int loop = 0; loop < dataSize; ++loop)
                {
                    // Because we use placement new we must explicitly destroy all members.
                    data[loop].~T();
                }
                free(data);
            }
            vector()
                : dataSize(0)
                , reserved(10)
                , data(NULL)
            {
                reserve(reserved);
            }
    
            vector(const vector<T> &other)
                : dataSize(0)
                , reserved(other.dataSize)
                , data(NULL)
            {
                reserve(reserved);
                dataSize = reserved;
                for(unsigned int loop;loop < dataSize;++loop)
                {
                    // Because we are using malloc/free
                    // We need to use placement new to add items to the data
                    // This way they are constructed in place
                    new (&data[loop]) T(other.data[loop]);
                }
            }
    
            vector(unsigned int init_num)
                : dataSize(0)
                , reserved(init_num)
                , data(NULL)
            {
                reserve(reserved);
                dataSize = reserved;
                for(unsigned int loop;loop < dataSize;++loop)
                {
                    // See above
                    new (&data[loop]) T();
                }
            }
    
            const vector<T>& operator= (vector<T> x)
            {
                // use copy and swap idiom.
                // Note the pass by value to initiate the copy
                swap(dataSize, x.dataSize);
                swap(reserved, x.rserved);
                swap(data,     x.data);
    
                return *this;
            }
    
            void reserve(unsigned int new_size)
            {
                if (new_size < reserved)
                {    return;
                }
    
                T*  newData = (T*)malloc(sizeof(T) * new_size);
                if (!newData)
                {    throw int(2);
                }
    
                for(unsigned int loop = 0; loop < dataSize; ++loop)
                {
                    // Use placement new to copy the data
                    new (&newData[loop]) T(data[loop]);
                }
                swap(data, newData);
                reserved    = new_size;
    
                for(unsigned int loop = 0; loop < dataSize; ++loop)
                {
                    // Call the destructor on old data before freeing the container.
                    // Remember we just did a swap.
                    newData[loop].~T();
                }
                free(newData);
            }
    
            void push_back(const T &item)
            {
                if (dataSize == reserved)
                {
                    reserve(reserved * 2);
                }
                // Place the item in the container
                new (&data[dataSize++]) T(item);
            }
    
            unsigned int  size() const  {return dataSize;}
            bool          empty() const {return dataSize == 0;}
    
            // Operator[] should NOT check the value of i
            // Add a method called at() that does check i
            const T& operator[] (unsigned i) const      {return data[i];}
            T&       operator[] (unsigned i)            {return data[i];}
    
            void insert(unsigned int pos, const T& value)
            {
                if (pos >= dataSize)         { throw int(1);}
    
                if (dataSize == reserved)
                {
                        reserve(reserved * 2);
                }
                // Move the last item (which needs to be constructed correctly)
                if (dataSize != 0)
                {
                    new (&data[dataSize])  T(data[dataSize-1]);
                }
                for(unsigned int loop = dataSize - 1; loop > pos; --loop)
                {
                    data[loop]  = data[loop-1];
                }
                ++dataSize;
    
                // All items have been moved up.
                // Put value in its place
                data[pos]   = value;
            }
    
            void clear()                                        { erase(0, dataSize);}
            void erase(unsigned int erase_index)                { erase(erase_index,erase_index+1);}
            void erase(unsigned int start, unsigned int end)    /* end NOT inclusive so => [start, end) */
            {
                if (end > dataSize)
                {   end     = dataSize;
                }
                if (start > end)
                {   start   = end;
                }
                unsigned int dst    = start;
                unsigned int src    = end;
                for(;(src < dataSize) && (dst < end);++dst, ++src)
                {
                    // Move Elements down;
                    data[dst] = data[src];
                }
                unsigned int count = start - end;
                for(;count != 0; --count)
                {
                    // Remove old Elements
                    --dataSize;
                    // Remember we need to manually call the destructor
                    data[dataSize].~T();
                }
            }
            unsigned int begin() const  {return 0;}
    
    
    }; //class vector
    
    #包含//表示空
    #包括//因为您需要新的位置
    //因为你在避免性病:
    //swap的实现
    模板
    无效掉期(T&lhs、T&rhs)
    {
    T tmp=lhs;
    lhs=rhs;
    rhs=tmp;
    }
    模板
    类向量
    {
    私人:
    无符号整数数据大小;
    无符号整数保留;
    T*数据;
    公众:
    ~vector()
    {
    for(无符号整数循环=0;循环