簡體   English   中英

調用delete []會破壞我的C ++程序

[英]Calling delete[] breaks my C++ program

更新:感謝您的快速答復。 看來我已經發布了舊版本的代碼。 除了參數化的構造函數外,其他所有內容均相同。 如您所見,代碼中存在一些缺陷,但是請記住,我還沒有完全完成此工作。 目前,我更擔心數組,因為這是昨天引入的新概念。 我嘗試了幾種不同的方法,並進行了數小時的研究。 大多數響應都說只使用向量類,但這是用於家庭作業的,這有助於我們了解內存分配和動態數組。 目前,這是我的.cpp和.h文件,給我帶來了問題。 每次觸發刪除(或清除功能)操作時,都會發生錯誤,指出blahblah.exe已觸發斷點。

MyVector.h

#pragma once

class MyVector
{
private:
    int arraySize; 
    int arrayCapacity;
    int* theData;
    void grow();

public:
    MyVector();
    MyVector(int n);
    int size() const;
    int capacity() const;
    void clear();
    void push_back(int n);
    int& at(int n);
    ~MyVector();
};

MyVector.cpp

   #include "MyVector.h"
    #include <iostream>
    using namespace std;

    MyVector::MyVector()
    {
    arraySize = 0;
    arrayCapacity = 0; 
    theData = new int[0];
    }
    MyVector::MyVector(int capacityIn)
    {
    theData = new int [capacityIn];
    arraySize = 0;
    arrayCapacity = 0;
    }
    int MyVector::size() const
    {
    return arraySize;
    }
    int MyVector::capacity() const
    {
    return arrayCapacity;
    }
    void MyVector::clear()
    {
        delete [] theData;
        theData = nullptr;
    }
    void MyVector::push_back(int n)
    {
        if (arrayCapacity==0)
        {
        arrayCapacity++;
        MyVector(arrayCapacity);
    }
    if (arraySize == arrayCapacity)
    {
        grow();
        MyVector(arrayCapacity);
    }
    theData[arraySize] = n;
    arraySize++;
}
int& MyVector::at(int index)
{
    if (index >= 0 && index<arraySize)
    {
        return (theData[index]);
    }
    else
    {
        throw index;
    }
}
void MyVector::grow()
{
    arrayCapacity = arrayCapacity + arrayCapacity;
}

MyVector::~MyVector()
{
    if (theData != nullptr)
    {
        clear();
    }
}

您有很多問題,我已經可以看到:

  1. 您不應像這樣顯式調用構造函數。 它沒有按照您的想法做。 將分配放入真實的成員函數中。
  2. 每次“增長”數組時,您都只是分配新數組,這會導致泄漏,因為之前的指針沒有被刪除。
  3. 您要問的主要問題:您甚至沒有將分配的指針存儲在構造函數中。 更改int* theData = new int [capacityIn]; theData = new int [capacityIn]; 例如,您在第一個構造函數中做的正確。
  4. 您還沒有初始化arraySizearrayCapacity在你的第二個構造函數( MyVector(int)

刺針:

  1. 刪除之前,無需檢查nullptr
  2. 不需要new int[0] 您永遠不要訪問內存,因此只需將其初始化為nullptr

這里:

MyVector::MyVector(int capacityIn)
{
  int* theData = new int [capacityIn];
}

您聲明一個局部指針theData ,該指針theData了當前對象的theData數據成員, theData初始化它。 從那里開始,所有賭注都禁止使用它,純屬偶然,因為它是delete[]程序最終崩潰的地方。

MyVector::MyVector(int capacityIn)
{
  theData = new int [capacityIn];
}

相反,和arraySizearrayCapacity將不得不以及初始化。

除此之外,您還會遇到這樣的問題

MyVector(arrayCapacity);

push_back函數中分配一個MyVector類型的臨時對象,該對象(幾乎)立即被再次銷毀; 它不會更改當前對象。

這導致您無法解決的問題:

int* theData = new int [capacityIn];

您在說:“請定義一個整數指針...”,依此類推。 成員變量不同於您在方法內部定義的變量。 這樣做是沒有意義的。 相反,您應該這樣做:

theData = new int [capacityIn];

或者,僅出於教育目的(為了使您理解,我們將其分配給成員變量):

this->theData = new int [capacityIn];

另外(某些觀點可能並不那么重要,但由於您是新手,所以我想指出這些觀點):

  1. 請在第二個構造函數中設置其他變量,看來您已經忘記這樣做了。

     MyVector::MyVector(int capacityIn) { theData = new int [capacityIn]; arraySize = capacityIn; arrayCapacity = capacityIn; } 
  2. 您應該使用有意義的名稱,您絕對應該避免使用theData http://petdance.com/2012/04/the-worlds-two-worst-variable-names/

  3. 您的方法應以動詞開頭,例如getDimension() getCapacity()等。
  4. 構造函數是... 構造函數 ,這意味着在構造創建項目時都將調用它們。 您絕對不應該以任何方式顯式調用構造函數。
  5. 這是一條基本規則:每當您使用new命令訪問內存時,都應在一段時間后調用delete 您的代碼存在嚴重的內存泄漏。

我也許可以為您提供更多幫助,但是我無法完全理解您要通過某些方法(即grow()pushBack()

通過構造函數體內的賦值語句初始化變量的樣式不好。 相反,應在輸入構造函數主體之前初始化變量。

您可以通過使用成員初始化器列表或在類定義中提供默認值來執行此操作。 后者似乎在這里最簡單:

class MyVector
{
private:
    int arraySize = 0;
    int arrayCapacity = 0;
    int* theData = nullptr;
    // ....

然后在構造函數中,而不是復制代碼,您應該利用現有函數來執行相同的操作:

MyVector::MyVector(int capacityIn)
{
     // call function which increases capacity to match capacityIn.
}

當前,您實際上沒有增加容量的功能,因此您需要添加一個。 grow()函數使int變量增加,但是您不分配更多的內存,因此這只會導致您的代碼寫在實際分配的空間的末尾)。

它可能看起來像:

void grow( int newCapacity )
{
    if ( newCapacity < arrayCapacity )
        return;   // we do not need to shrink

    int *newData = new int [new_capacity];
    if ( arraySize > 0 )
        std::copy(arrayData, arrayData + arraySize, newData);
    delete[] arrayData;
    newData = arrayData;
}

然后,您可以修改grow() (如果您仍然想要保留它)和push_back()以也調用此函數。


注意, clear()函數只需要執行arraySize = 0; 它不需要釋放任何內存。 您可以將該容量留作將來使用。

暫無
暫無

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

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