[C ++矩阵破坏导致断点和严重错误

问题描述 投票:-1回答:2

所以我想创建一个4x4矩阵类,将其数据存储为float** m。我像这样初始化它:

Matrix4f::Matrix4f()
{
    this->m = new float*[4];

    for (int i = 0; i < 4; i++)
    {
        this->m[i] = new float[4];
        memset(this->m[i], 0, sizeof(float) * 4);
    }
}

在那之后,我有一个析构函数,像这样:

Matrix4f::~Matrix4f()
{
    for (int i = 0; i < 4; i++)
    {
        delete[] m[i];
    }

    delete[] m;
}

但是有时当我使用此类时,此行:

delete[] m[i];

导致断点,并引发:Critical error detected c0000374这是初始化和删除4x4矩阵的正确方法吗?

c++ arrays matrix constructor destructor
2个回答
0
投票

如前所述,这三个规则可能是问题。您提供的代码在技术上是正确的,但是,如果您复制Matrix4f,则必须重新实现复制构造函数和重载的赋值构造函数:

#include <iostream>


class Matrix4f
{
public:
    Matrix4f()
        : m_data(new float*[4])
    {
        for (int i = 0; i < 4; i++)
            m_data[i] = new float[4]{ 0 };
    }
    Matrix4f(const Matrix4f& source)
    {
        m_data = new float*[4];
        for (int i = 0; i < 4; i++)
        {
            m_data[i] = new float[4]{ 0 };
            for (int j = 0; j < 4; j++)
            {
                m_data[i][j] = source.m_data[i][j];
            }
        }
    }
    Matrix4f& operator=(const Matrix4f& source)
    {
        if (this == &source) return *this;

        clear();
        m_data = new float*[4];
        for (int i = 0; i < 4; i++)
        {
            m_data[i] = new float[4]{ 0 };
            for (int j = 0; j < 4; j++)
            {
                m_data[i][j] = source.m_data[i][j];
            }
        }

        return *this;
    }
    ~Matrix4f()
    {
        clear();
    }
//private:
    float**m_data;

    void clear()
    {
        if (m_data != NULL)
        {
            for (int i = 0; i < 4; i++)
            {
                delete[] m_data[i];
            }
            delete[]m_data;
        }
    }

    void print()const
    {
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                std::cout << m_data[i][j] << "\t";
            }
            std::cout << "\n";
        }
    }
};



int main()
{
    Matrix4f m1;

    m1.m_data[0][0] = m1.m_data[1][1] = m1.m_data[2][2] = m1.m_data[3][3]  = 1;

    {
        Matrix4f m2(m1);
        Matrix4f m3 = m2;

        m2.print();
        m3.print();
    }

    m1.print();
}

但是我建议您改用一维向量,它更快,更安全。


0
投票

如注释中所指出的,当且仅当您正确管理副本的情况时,您的代码才是好的。

您有三个选择:

  1. 禁用副本
  2. 浅拷贝
  3. 深层复制

让我们讨论这个选择:

  1. 您只需要声明复制构造函数和复制分配操作符即可。现在无法复制您的类的对象。这降低了矩阵类的有用性。

  2. 这本身没有任何实际价值。由于您可以通过将类型3的对象包装到std::shared_ptr中来实现此目的。

  3. 在这种情况下,不需要动态内存。即使有,您也想使用std :: vector或其他方法来管理内存。合理的解决方案是使用float[4][4]作为m。因为您避免了内存管理,所以这将更加健壮。

© www.soinside.com 2019 - 2024. All rights reserved.