0

我正在尝试使用模板开发一个通用列表。该列表由指针数组 T* 复合而成,它是一个用于获取元素数量的整数和一些方法(查找、包含...)。重要的是说我不能使用 std::library。

例如,当我使用 a 时,我的问题就出现了List<List<int> >

其中一种方法是调整T*指针数组的大小,所以当我有这个时,List<List>>我创建了一个比它更大的辅助指针,T*并将内容复制T到带有memcpy. 内部指针 ( list.T.T) 也被复制为指针,而不是内存复制,所以当我删除T*指针并重新签名时T=auxpointer。我已经在我的new T.

template <typename T>
void CGenericList<T>::resize()
{
    T* auxPointer = new T[this->maxElements*2];
    memcpy (auxPointer,this->pointer,this->maxElements*sizeof(T));
    delete[] this->pointer;     
    this->pointer=auxPointer;
    this->maxElements=2*this->maxElements;
}

template<class T>
class CGenericList
{
public:
    T* pointer;
    int N;
    int maxElements;

    CGenericList();
    CGenericList(int);
    ~CGenericList();
    void resize();  
}

任何人都可以给我任何提示吗?

4

2 回答 2

3

您发布的代码显示了一些问题。

T* auxPointer = new T[this->maxElements*2];

在这里,您分配一个新的 maxElements*2 数组 - 并调用默认构造函数。在您的情况下,这可能会初始化所有 Listelements。

memcpy (auxPointer,this->pointer,this->maxElements*sizeof(T));

之后,您将旧数组的内容复制到新分配内存的内存区域。这会用旧数组中的指针覆盖指向刚刚创建的 Listelements -> 内存泄漏的指针。

delete[] this->pointer;

然后你删除数组,这会调用所有元素的析构函数。希望这会删除他们的内容并释放他们的记忆。

this->pointer=auxPointer;

最后,您重新分配新创建的数组。列表中的指针指向旧的列表元素,并且不再指向未分配的内存(因为通过 delete[] 调用了析构函数)。

一个解决方案是为您的列表实现一个复制构造函数,并为数组中的所有元素调用它。(DeepCopy)当然还有一个赋值运算符,我差点忘了;)

CGenericList(const CGenericList<T>& copy);
CGenericList<T>& operator= (const CGenericList<T>& rhs)

可能是这样的 - 请注意,这是“asis”,绝对不是异常安全的;)

template<class T>
class CGenericList
{
public:
    T* pointer;
    int N;
    int maxElements;

    CGenericList();
    CGenericList( const CGenericList<T>& copy );
    CGenericList<T>& operator=(const CGenericList<T>& rhs);
    CGenericList(int);
    ~CGenericList();
    void resize();
};

template <typename T>
void CGenericList<T>::resize()
{
    T* auxPointer = new T[this->maxElements*2];
    for(int i=0; i < this->maxElements; i++)
    {
        auxPointer[i] = this->pointer[i];
    }
    delete[] this->pointer;
    this->pointer = auxPointer;
    this->maxElements = this->maxElements*2;
}

template <typename T>
CGenericList<T>::CGenericList()
    :N(0)
    ,maxElements(0)
{
    this->pointer = new T[1];
}

template <typename T>
CGenericList<T>::CGenericList(const CGenericList<T>& copy)
    :N(copy.N)
    ,maxElements(copy.maxElements)
{
    T* temp = new T[copy.maxElements];
    for(int i=0; i<N; i++ )
    {
        temp[i] = copy.pointer[i];
    }
    this->pointer = temp;
}

template <typename T>
CGenericList<T>& CGenericList<T>::operator=(const CGenericList<T>& rhs)
{
    if( this != &rhs )
    {
        delete[] this->pointer;
        this->pointer = new T[rhs.maxElements];
        for(int i=0; i<rhs.maxElements; i++)
        {
            this->pointer[i] = rhs.pointer[i];
        }
    }
    return *this;
}


template <typename T>
CGenericList<T>::CGenericList(int size)
    :N(0)
    ,maxElements(size)
{
    this->pointer = new T[size];
}

template <typename T>
CGenericList<T>::~CGenericList()
{
    delete[] this->pointer;
}


int main(int /*argc*/, char */*argv*/[])
{
    CGenericList<CGenericList<int> > list;
    list.resize();

    return 0;
}

如果你不喜欢使用 stl 你可以看看stlport

于 2012-05-24T10:27:59.130 回答
0

resize不是例外安全的。您首先删除现有数组,然后为不同大小分配内存,然后分配 auxPointer。
遇到您遇到的问题,请检查以下方法是否有帮助。

T* auxPointer = new T[this->maxElements*2];       
for ( int i =0; i < this->maxElements; ++i)
   std::swap(auxPointer[i], pointer[i]);

delete[] this->pointer;    
this->pointer = auxPointer;  
this->maxElements=2*this->maxElements;
于 2012-05-24T09:24:15.107 回答