九天雁翎的博客
如果你想在软件业获得成功,就使用你知道的最强大的语言,用它解决你知道的最难的问题,并且等待竞争对手的经理做出自甘平庸的选择。 -- Paul Graham

个人研究《数据结构与算法分析-C++描述》Vector实现的问题,new与初始化


 个人研究《数据结构与算法分析-C++描述》Vector实现的问题,new与初始化

write by 九天雁翎(JTianLing) --
blog.csdn.net/vagrxie

 

<<Data Structures and Algorithm Analysis in C++>>

--《数据结构与算法分析c++描述》 Mark Allen Weiss 人民邮电大学出版 中文版第61面, 图3-7,3-8,实现的一个列表Vector类。

原实现大概如下:(我可能修改了一些变量的命名以符合我的习惯)


template<typename T>

class Vector

{

public:

    explicit Vector(unsigned auInitSize
= 0)

       : muSize(auInitSize),muCapacity(auInitSize + SPARE_CAPACITY)

    {

       mpObjects = new T[muCapacity];

    }

 

    Vector(const Vector &aoObject):mpObjects(0)

    {

       *this = aoObject;

    }

 

    ~Vector()

    {

       delete[] mpObjects;

    }

 

    const Vector&
operator= (const
Vector &aoObject)

    {

       if(this
== &aoObject)

       {

           return *this;

       }

      

       delete[] mpObjects;

       muSize = aoObject.size();

       muCapacity = aoObject.capacity();

 

       mpObjects = new T[ capacity() ];

 

       for(unsigned
i=0; i!=muSize; ++i)

       {

           mpObjects[i] = aoObject[i];

       }

 

       return *this;

    }

 

    void resize(unsigned auNewSize)

    {

       if ( auNewSize
> muCapacity )

       {

           reserve(auNewSize * 2 + 1);

       }

    }

 

    void reserve(unsigned auNewCapacity)

    {

       if(auNewCapacity
< muSize)

       {

           return;

       }

 

       T *lpOldArray
= mpObjects;

 

       mpObjects = new T[auNewCapacity];

       for(unsigned
i=0; i!=muSize; ++i)

       {

           mpObjects[i] = lpOldArray[i];

       }

      

       muCapacity = auNewCapacity;

 

       delete[] lpOldArray;

    }

 

    T& operator[](unsigned auIndex)

    {

       return mpObjects[auIndex];

    }

 

    const T&
operator[](unsigned
auIndex) const

    {

       return mpObjects[auIndex];

    }

 

    bool empty()
const

    {

       return (muSize == 0);

    }

 

    unsigned size()
const

    {

       return muSize;

    }

 

    unsigned capacity()
const

    {

       return muCapacity;

    }

 

    void push_back(const T& aoObject)

    {

       if(muSize
== muCapacity)

       {

           reserve(2 * muCapacity + 1);

       }

 

       mpObjects[muSize++] = aoObject;

    }

 

    void pop_back()

    {

       muSize--;

    }

 

    const T&
back() const

    {

       return mpObjects[muSize-1];

    }

 

    typedef T*
iterator;

    typedef const
T* const_iterator;

 

    iterator begin()

    {

       return mpObjects;

    }

 

    const_iterator begin() const

    {

       return mpObjects;

    }

 

    iterator end()

    {

       return mpObjects + muSize;

    }

 

    const_iterator end() const

    {

       return mpObjects + muSize;

    }

 

    enum { SPARE_CAPACITY
= 16 };

 

private:

    unsigned muSize;

    unsigned muCapacity;

    T *mpObjects;

};

 

首先的第一个感觉就是new了以后没有初始化,而且放任其未初始化的值的使用。(说的这么复杂,就是说使用了没有初始化的值贝)

但是实际我在Linux下测试的时候发现,g++是会自动将所有new出来的内存初始化的,事实就是如此,这和我在windows下的常识有冲突,所以特意做了一个测试程序来实验。

 

int main( void )

{

    int *lpi
= new int[100];

 

    for(int
i=0; i<100;
++i)

    {

       printf("%d",lpi[i]);

    }

 

    return 0;

}

 

linux下总是会输出全0,哪怕我怀疑碰巧这段内存没有被使用过,将100变成1000也是全0.只能承认,new以后是自动初始化的了。

我甚至怀疑我的常识是否是错误的(虽然我以前为了保证初始化,认为每次new完以后,哪怕马上要全部的使用这些内存都会先用memset置空一下是个好的习惯)

 

事实上,在VS2005的测试中,结果我的常识一样,在debug版本下,windows会自动置为0xcdcdcdcd等值,release时为随机值。

我只能说,以前我一直没有注意到g++编译下自动初始化的事实。

然后我特意看了一下VSlibstdc++vector实现,在resize(size)的时候都是T()作为第二参数调用重载的另一个函数resize(size,val)来实现的,也就是说,C++标准库的这两个实现还是确保reseize初始化了。

ok,也许Mark Allen WeissVectorLinux下可以不出错。。。但是我还是认为这个程序写的有问题,加上初始化吧。。。。。。

自己Mark一下,原来g++编译的new带初始化的?希望有高人能够给我解答,假如不是g++编译的new带初始化那么是什么情况导致了这样的情况,还有,g++有关掉初始化的选项吗?

 write by 九天雁翎(JTianLing) -- www.jtianling.com

 

分类:  Linux  算法 
标签:  C++  Vector  《数据结构与算法分析-C++描述》 

Posted By 九天雁翎 at 九天雁翎的博客 on 2008年12月05日

前一篇: 一个无聊男人的疯狂《数据结构与算法分析-C++描述》学习笔记 用C++/lua/python/bash的四重实现(7)习题2.8 随机数组的三种生成算法 后一篇: 漫谈C++中的宏