无效的分配大小(在派生类复制构造函数中)

时间:2012-03-17 15:16:03

标签: c++ inheritance memory-management

我已将我的问题缩小到派生类复制构造函数,但我不确定原因。 编辑: M,N和数据是私有的。我收到的错误是'无效的分配大小:4294967295字节' - 据我所知,这是在将-1传递给new时引起的。我不确定为什么会发生这种情况,除非在课堂通讯时数据丢失。

BinaryMatrix::BinaryMatrix(const BinaryMatrix& copy) : Matrix(copy)
{
    //cout << "Copy Constructor\n";

    M = copy.M;
    N = copy.N;

    data = new double[M*N]; //This line causes the allocation error

    for (int i = 0; i < M; i++)
    {
            for (int j = 0; j < N; j++)
            {
                    data[i*N+j] = copy.data[i*N+j];
            }
    }
}

以上是我的派生副本构造函数,它会导致错误。我已经标记了分配线。

我只能假设没有正确读取M和N.虽然我不确定为什么。我将包括派生和基础构造函数,以及基本副本。

感谢您的帮助。

MATRIX(BASE)CONSTRUCTOR

Matrix::Matrix(int M, int N, double* input_data)
{
    this->M = M;
    this->N = N;

    //cout << "Matrix Constructor\n";
    data = new double[M*N];

    for (int i = 0; i < M; i++)
    {
            for (int j = 0; j < N; j++)
            {
                    data[i*N+j] = input_data[i*N+j];
            }
    }

    delete [] input_data;
}

MATRIX(BASE)COPY CONSTRUCTOR

Matrix::Matrix(const Matrix& copy)
{
    //cout << "Copy Constructor\n";

    M = copy.M;
    N = copy.N;

    data = new double[M*N];

    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            data[i*N+j] = copy.data[i*N+j];
        }
    }
}

BINARYMATRIX(派生)构造函数

BinaryMatrix::BinaryMatrix(int M, int N, double* input_data) : Matrix(M, N, input_data)
{
    data = new double[M*N];

    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            this->data[i*N+j] = this->getRead(i, j);
        }
    }

    double thr_val = this->Mean();

    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < N; j++)
        {
            if (this->data[i*N+j] > thr_val)
                this->data[i*N+j] = 1;

            if (this->data[i*N+j] < thr_val)
                this->data[i*N+j] = 0;
        }
    }
}

3 个答案:

答案 0 :(得分:1)

为什么要在BinaryMatrix复制构造函数中创建矩阵数据的新副本?您从Matrix复制构造函数调用的BinaryMatrix的复制构造函数已经执行此操作。

BinaryMatrix复制构造函数中,您放弃了Matrix复制构造函数已经创建的矩阵数据的副本(没有delete)并创建一个新的。这是一个内存泄漏 - 如果你经常这样做,内存将会耗尽。

答案 1 :(得分:0)

如果错误是M和N是私人的。那么你必须将保护级别更改为受保护或公共或提供访问方法。在私有的基类中定义的Vairables是派生类无法通行的。

class A
{
    int x;
}

class B : public A
{
    int DoSomething()
    { 
        return x; //This is an error X is private to class A and as such inaccessible. 
    }

}

答案 2 :(得分:0)

如果MNMatrix是私有的而BinaryMatrix来自Matrix,我不确定您的代码编译的原因(您不应该能够访问BinaryMatrix中的M,N。如果您的BinaryMatrix声明还包括成员MN(以及Matrix::NMatrix::M),那么这可能是问题的根源。< / p>

如果BinaryMatrix未声明MN,那么我认为我们仍然没有足够的数据来诊断您的问题。要猜一点,也许M * N不适合用于M的类型。所以你有算术溢出。数组大小在size_t中指定,因此强制转换可以正常工作。

此外,您可能希望将数据管理委托给其中一个类。也就是说,做到这一点:

BinaryMatrix::BinaryMatrix(const BinaryMatrix& copy) : Matrix(copy)
{
    // M, N, data already set in Matrix::Matrix(const Matrix&)
    // The data has also been copied, so there is nothing to do here.
}

或者这个:

#include <algorithm>

BinaryMatrix::BinaryMatrix(const BinaryMatrix& copy) 
 : Matrix(), M(0), N(0), 
   data(0) // null in case new throws an exception (avoid bad delete in dtor).
{
    const size_t nelems(size_t(copy.M)*size_t(copy.N));
    data = new double[nelems];
    M = copy.M;
    N = copy.N;
    stl::copy(copy.data, copy.data+nelems, data);
}

我认为通常使用int迭代动态数据结构不是一个好主意,因为没有什么能保证结构的实际大小符合int。但是size_t确实存在该保证(任何现有对象必须具有size_t中可表示的大小,因此您可以使用size_t迭代任何连续对象。

事实上,我不确定你试图从MatrixBinaryMatrix获得什么区别(目的或行为)。数据似乎具有相同的表示。如果它是行为的差异而不是您正在寻找的表示,我认为使用组合(即,单独的未继承的表示类)而不是继承可能更好。请参阅What is the Liskov Substitution Principle?,了解如何有效地思考何时使用继承。

但是,如果到目前为止您所看到的答案实际上都没有帮助解决您的问题,那么您应该花一些时间来减少您的示例:什么是最小的完整示例程序来演示您的问题?张贴。