簡體   English   中英

Memory C++ 中的分配(拋出異常:讀取訪問沖突。)

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

我正在嘗試更多地了解 C++。 在使用 memory 分配一段時間后,我到了一個我很難理解它的地方。

我為一種初始化類型(某個類的 object)編寫了一個運行良好的代碼(不太確定,但至少沒有顯示任何 memory 違規),但它在類似初始化時崩潰。

如果有人能解釋發生了什么以及如何解決這個問題,我將不勝感激。

我的想法:問題出在下面一行,因為我試圖在有問題的初始化中刪除一組分配的對象,我只分配了一個 object 而不是一個數組。

delete[] pointer; //PROBLEMATIC LINE

PS.:我不是在尋找替代解決方案(例如使用智能指針或其他)。 對不起我的英語不好!

編碼:

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];

導致未定義的行為。 在使用之前從other.s中設置s


你的第二個構造函數有同樣的問題。


您的class1賦值運算符正在泄漏 memory,因為它不會delete[]前一個數組。


class2中,您使用非數組形式的new ,例如這里:

pointer = new class1(un, uarray);

但是在析構函數中,您調用delete[]來刪除pointer 這也會導致未定義的行為。 new的非數組版本返回的指針需要被delete ,例如delete pointer

但是由於您還使用new的數組版本作為pointer ,所以您也不能使用delete pointer 由於在從新數組返回的指針上使用delete而不是delete[]也具有未定義的行為。

保持一致並始終使用新數組,例如:

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

當復制或移動其類型的 object 時, class2會導致未定義的行為,因為盡管您定義了析構函數,但您沒有實現復制構造函數和賦值運算符。 這違反了三原則


我可能錯過了更多。 代碼根本不可讀。 下次請使用正確的變量名。 (我希望真正的代碼不使用這種命名方案......)例如,具有與該 class 的成員同名的非類型模板參數m然后在該上下文的多個位置使用m是不行的。 我必須檢查查找規則以確保它確實可以編譯並執行一些合理的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM