C++中的内存分配(异常抛出:读访问违例) 我正在努力学习更多的C++! 在对内存分配进行了一段时间的研究之后,我来到了一个我很难理解它的地方

C++中的内存分配(异常抛出:读访问违例) 我正在努力学习更多的C++! 在对内存分配进行了一段时间的研究之后,我来到了一个我很难理解它的地方,c++,memory,allocation,access-violation,C++,Memory,Allocation,Access Violation,我写了一段代码,它运行得很好,但并不确定这一点,但对于某类对象的初始化类型,它至少没有显示任何内存冲突,但对于类似的初始化,它会崩溃 如果有人能告诉我发生了什么以及我如何解决这个问题,我将不胜感激 我的想法是:问题在下面这行,因为我试图删除一个分配对象的数组,而在有问题的初始化中,我只分配了一个对象,而没有分配数组 delete[] pointer; //PROBLEMATIC LINE 注:我不是在寻找像使用智能指针之类的替代解决方案。对不起我的英语 守则: class class1 { p

我写了一段代码,它运行得很好,但并不确定这一点,但对于某类对象的初始化类型,它至少没有显示任何内存冲突,但对于类似的初始化,它会崩溃

如果有人能告诉我发生了什么以及我如何解决这个问题,我将不胜感激

我的想法是:问题在下面这行,因为我试图删除一个分配对象的数组,而在有问题的初始化中,我只分配了一个对象,而没有分配数组

delete[] pointer; //PROBLEMATIC LINE
注:我不是在寻找像使用智能指针之类的替代解决方案。对不起我的英语

守则:

class class1
{
private:
    unsigned int    s;
    double* pointer;
public:
/* Constructors */
    class1() { s = 0; pointer = nullptr; }
    class1(unsigned int us, double* uarray)
    {
        pointer = new double[us];
        for (unsigned int i = 0; i < us; i++)
            pointer[i] = uarray[i];
    }
    class1(const class1& other)
    {
        pointer = new double[s];
        for (unsigned int i = 0; i < s; i++)
            pointer[i] = other.pointer[i];
    }
    ~class1() { if (!s && pointer != nullptr) delete[] pointer; }

public:
/* Operators Overloading */
    class1& operator=(const class1& other)
    {
        s = other.s;
        pointer = new double[s];
        for (unsigned int i = 0; i < s; i++)
            pointer[i] = other.pointer[i];
        return *this;
    }
};

class class2
{
private:
    unsigned int    m;
    unsigned int    n;
    class1* pointer;

public:
/* Constructors */
    class2(unsigned int un, double* uarray, bool flag = false) : n(un)
    {
        m = 1;
        pointer = new class1(un, uarray);
        if (flag) { this->function(); }
    }
    ~class2() { if (!m && !n) delete[] pointer; }

public:
/* Public Methods */
    void function()
    {
        class1* newpointer = new class1[n];
        //**... some code (when commented show the same error)**
        delete[] pointer; //**PROBLEMATIC LINE**
        pointer = newpointer;
    }

public:
/*Template Constructor*/
    template<unsigned int m, unsigned int n>
    class2(unsigned int um, unsigned int un, double(&uarray)[m][n], bool flag = false) : m(um), n(un)
    {
        pointer = new class1[um];
        for (unsigned int i = 0; i < um; i++)
        {
            class1 object1(un, uarray[i]);
            pointer[i] = object1;
        }
        if (flag) { this->function(); }
    }
};

int main()
{
    double test3[] = { 1, 2, 3 };
    double test4[][3] = { {3, 2, 1}, {6, 5, 4}, {9, 8, 7} };
    double test5[][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };

    class2 m4(3, test3, true);      //**NOT OK - VIOLATION OF MEMORY**
    class2 m5(3, 3, test4, true);   //**OK**
}
class1的复制构造函数未设置s成员,但在此处使用其不确定值:

pointer = new double[s];
导致未定义行为的。在使用之前,从其他.s设置s

第二个构造函数也有同样的问题

class1的赋值运算符正在泄漏内存,因为它没有删除前面的数组[]

在class2中,在非数组形式中使用new,例如:

pointer = new class1(un, uarray);
但在析构函数中调用delete[]来删除指针。这也会导致未定义的行为。从new的非数组版本返回的指针需要通过delete删除,例如delete pointer

但由于您也在使用new for pointer的数组版本,因此也不能使用delete pointer。对于从数组返回的指针使用delete而不是delete[],new也有未定义的行为

保持一致并始终使用新阵列,例如:

pointer = new class1[1]{{un, uarray}};
当复制或移动其类型的对象时,class2会导致未定义的行为,因为虽然定义了析构函数,但没有实现复制构造函数和赋值运算符。这违反了法律


我可能错过了更多。代码根本不可读。下次请使用正确的变量名。我希望真正的代码不使用这个命名方案。。。例如,使用与该类成员同名的非类型模板参数m,然后在该上下文的多个位置使用m是不正确的。我必须检查查找规则,以确保它确实编译并执行合理的操作。

s也没有在双参数构造函数中设置。是的,这是一个问题,但不是唯一的问题。例如,询问者声明删除[]指针;导致问题,在一种情况下,指针可能已分配为pointer=new CLASSION UN,uarray;。这是由于将new和delete[]混合在一起而造成的。另外,请参阅这篇关于delete[]和delete之间区别的文章。函数中还有未初始化的变量用法,直接从显示的代码调用。基本上,显示的代码是一个完整的、完全混乱的代码。此外,作为额外的奖励,还有一些有用的注释指示删除的代码,这可能隐藏了许多其他惊喜。@SamVarshavchik最初我认为我可以检查代码并将错误逐一添加到我的答案中。这可能是个错误。我至少看到了三个未定义行为的实例,即函数中未初始化的变量用法,在特定代码路径后的一个析构函数中,在复制构造函数中,以及其他类似的错误。显示的代码需要从零开始废弃和重写。请不要更正代码中与您的问题相关的错误。这使得其他人无法理解问题和答案。我回滚了您的编辑。