简体   繁体   English

Memory C++ 中的分配(抛出异常:读取访问冲突。)

[英]Memory Allocation in C++ (Exception thrown: read access violation.)

I'm trying to learn a little bit more of C++.我正在尝试更多地了解 C++。 After working around with memory allocation for a while I got to a place where I'm struggling to understand it.在使用 memory 分配一段时间后,我到了一个我很难理解它的地方。

I wrote a code that works well (not really sure of that but at least doesn't show any memory violation) for a type of initialization (of an object of some class) but it crashes for a similar initialization.我为一种初始化类型(某个类的 object)编写了一个运行良好的代码(不太确定,但至少没有显示任何 memory 违规),但它在类似初始化时崩溃。

I would appreciate if someone could me explain what is happening and how can I solve this problem.如果有人能解释发生了什么以及如何解决这个问题,我将不胜感激。

My thought: The problem is in the line bellow because I'm trying to delete an array of allocated objects when in the problematic initialization I only have one object allocated and not an array.我的想法:问题出在下面一行,因为我试图在有问题的初始化中删除一组分配的对象,我只分配了一个 object 而不是一个数组。

delete[] pointer; //PROBLEMATIC LINE

PS.: I'm not looking for alternative solutions (like using smart-pointers or whatever). PS.:我不是在寻找替代解决方案(例如使用智能指针或其他)。 Sorry for my English!对不起我的英语不好!

The code:编码:

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**
}

Your copy constructor for class1 is not setting the s member, but uses its indeterminate value here:您的class1复制构造函数没有设置s成员,而是在此处使用其不确定值:

pointer = new double[s];

causing undefined behavior.导致未定义的行为。 Set s from other.s before using it.在使用之前从other.s中设置s


Your second constructor has the same problem.你的第二个构造函数有同样的问题。


Your assignment operator of class1 is leaking memory, because it doesn't delete[] the previous array.您的class1赋值运算符正在泄漏 memory,因为它不会delete[]前一个数组。


In class2 you use new in the non-array form, eg here:class2中,您使用非数组形式的new ,例如这里:

pointer = new class1(un, uarray);

but in the destructor you call delete[] to delete pointer .但是在析构函数中,您调用delete[]来删除pointer This is also causing undefined behavior.这也会导致未定义的行为。 Pointers returned from the non-array version of new need to be deleted by delete , eg delete pointer .new的非数组版本返回的指针需要被delete ,例如delete pointer

But since you are also using the array version of new for pointer , you cannot use delete pointer either.但是由于您还使用new的数组版本作为pointer ,所以您也不能使用delete pointer As using delete instead of delete[] on a pointer returned from a array-new has also undefined behavior.由于在从新数组返回的指针上使用delete而不是delete[]也具有未定义的行为。

Be consistent and use always the array-new, eg:保持一致并始终使用新数组,例如:

pointer = new class1[1]{{un, uarray}};

class2 causes undefined behavior when an object of its type is copied or moved, because you didn't implement a copy constructor and assignment operator although you have defined a destructor.当复制或移动其类型的 object 时, class2会导致未定义的行为,因为尽管您定义了析构函数,但您没有实现复制构造函数和赋值运算符。 This is a violation of the rule-of-three .这违反了三原则


There is probably more that I missed.我可能错过了更多。 The code is not readable at all.代码根本不可读。 Please use proper variable names next time.下次请使用正确的变量名。 (I hope that the real code does not use this naming scheme...) Eg having a non-type template parameter m with the same name as a member of that class and then using m in multiple places of that context is not ok. (我希望真正的代码不使用这种命名方案......)例如,具有与该 class 的成员同名的非类型模板参数m然后在该上下文的多个位置使用m是不行的。 I had to check the lookup rules to make sure that this actually compiles and does something sensible.我必须检查查找规则以确保它确实可以编译并执行一些合理的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 抛出C ++异常:读取访问冲突。 这是nullptr - C++ Exception thrown: read access violation. this was nullptr C ++-引发异常:读取访问冲突。 变量为nullptr - C++ - Exception thrown: read access violation. Variable was nullptr 抛出异常:写访问冲突。 这是 nullptr (C++) - Exception thrown: write access violation. this was nullptr (C++) 抛出异常:读取访问冲突。 这是 nullptr - Exception thrown: read access violation. this was nullptr 引发Visual Studio C ++异常:读取访问冲突。 使用命令行参数进行调试时 - Visual Studio C++ Exception thrown: read access violation. When debugging using Command Line Argument 引发异常:读取访问冲突。 此-&gt; m_pRenderTarget为nullptr。 C ++ - Exception thrown: read access violation. this->m_pRenderTarget was nullptr. c++ C++:“抛出异常:读取访问冲突。” 将向量分配给另一个时 - C++: “Exception thrown: read access violation.” when assigning a vector to the other 抛出异常:读取访问冲突。 _Pnext 是 0x148F854。 (C++ 析构函数错误) - Exception thrown: read access violation. _Pnext was 0x148F854. (C++ Destructor Error) C ++ Battle4Zion项目引发未处理的异常:读取访问冲突。 **这**是nullptr。 发生了 - C++ Battle4Zion project Unhandled exception thrown: read access violation. **this** was nullptr. occurred (SDL渲染问题)C ++异常抛出:读取访问冲突。 这是nullptr - (SDL Render Problem) C++ Exception Thrown: read access violation. THIS was nullptr
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM