1

大家好,我在下面的代码
PointArray.h

#ifndef POINTARRAY_H_INCLUDED
#define POINTARRAY_H_INCLUDED

template <typename T>
class PointArray
{
private:
    int nSize;
    T *array[];
public:
    PointArray();
    PointArray(const T *points[],const int size);
    PointArray(const PointArray &pv);
    ~PointArray();
    int * get(const int position);//is same to array[position]
    const int * get(const int position) const;//is same to array[position]
    const int getSize() const;//get size of array
};

#endif // POINTARRAY_H_INCLUDED

PointArray.cpp

#include "PointArray.h"
#include<iostream>
#include <assert.h>
using namespace std;

template<class T>
PointArray<T>::PointArray(const T *points[],const int size)
{
    nSize=size;
    for (int i=0;i<size;i++)
    {
        array[i]=new T;
        *array[i]=*points[i];
    }
}

template<class T>
PointArray<T>::PointArray()
{
    nSize=0;
}

template<class T>
PointArray<T>::PointArray(const PointArray &pv)
{
    nSize=pv.getSize();
    for (int i=0;i<nSize;i++)
    {
        array[i]=new T;
        *array[i]=*(pv.get(i));
    }
}

template<class T>
const int PointArray<T>::getSize() const
{
    return nSize;
}

template<class T>
PointArray<T>::~PointArray()
{
    delete[] array;
    nSize=0;
}

template<class T>
int * PointArray<T>::get(const int position)
{
    assert(position>-1 && position<nSize);
    return array[position];
}

template<class T>
const int * PointArray<T>::get(const int position) const
{
    return array[position];
}

main.cpp

#include<iostream>
#include "PointArray.h"
#include "PointArray.cpp"
using namespace std;

int main()
{
    int x=22;
    int y=3;
    const int * a[2]={&x,&y};
    PointArray<int> p;
    PointArray<int> p2(a,2);
    PointArray<int> p3(p2);
    cout << p.getSize() << endl;
    cout << p2.getSize() << endl;
    cout << p3.getSize() << endl;
    return 0;
}

上面的代码应该打印

0
2
2

但输出是

9244616
9244600
2

当我再次运行它时9244616,它9244600被改变了。
什么是问题?

4

2 回答 2

2

你的问题是

T *array[];

您定义一个没有元素的指针数组。然后您尝试访问其(不存在的)元素,这会导致未定义的行为。

另一个未定义的行为是在析构函数中

delete[] array;

你应该只使用-eddelete[]的东西。不是。相反,您应该遍历所有元素(如果有的话)并删除它们中的每一个。new[]arrayarray

最好的解决方案是使用std::vector而不是数组。如果您坚持使用数组,请在构造函数中更改T* array[]T **array, 为其分配内存

array = new T*[size];

并在析构函数中删除所有数组元素,然后再删除数组本身。

于 2013-04-05T10:16:31.743 回答
1

问题是您将 cpp 文件包含在 main 中并在那里实现,模板实现应该在 h 文件中完成。你的 h 文件应该是:

 #ifndef POINTARRAY_H_INCLUDED
#define POINTARRAY_H_INCLUDED

template <typename T>
class PointArray
{
private:
    int nSize;
    T *array[];
public:
    PointArray()
    {
        nSize=0;
    }
    PointArray(const T *points[],const int size)
    {
        nSize=size;
        for (int i=0;i<size;i++)
        {
            array[i]=new T;
            *array[i]=*points[i];
        }
    }
    PointArray(const PointArray &pv)
    {
        nSize=pv.getSize();
        for (int i=0;i<nSize;i++)
        {
            array[i]=new T;
            *array[i]=*(pv.get(i));
        }
    }
    ~PointArray()
    {
        delete[] array;
        nSize=0;
    }
    int * get(const int position)
    {
        assert(position>-1 && position<nSize);
        return array[position];
    }
    const int * get(const int position) const
    {
        return array[position];
    }
    const int getSize() const { return nSize;}
};

#endif // POINTARRAY_H_INCLUDED

代码仍然有点难,分配也很糟糕(注意你在过程结束时得到堆断言)..但它对我有用:打印了 0 2 2 ......干杯。

(请注意:)

delete[] array;

是内存泄漏,因为您的对象不是一个数组,但您尝试定义指向数组的指针,您应该将其更改为

T** array

然后在数组第一个维度的析构函数循环处,然后执行delete[] array

于 2013-04-05T09:35:26.233 回答