[英]Why does deleting an allocated array cause a memory error?
我為教育目的實現了一個 ArrayList 類,但是在我的 expand() 方法中刪除數組時遇到了內存錯誤。
這是我的課程和所有重要的方法:
//create array with default size 2
template<class T>
ArrayList<T>::ArrayList(){
realSize = 2;
count = 0;
data = new T[realSize];
}
//destructor
template<class T>
ArrayList<T>::~ArrayList() {
delete []data;
}
//adds value to end of list
template<class T>
void ArrayList<T>::add(T val) {
//if reached end of array, expand array
if (count >= realSize)
expand();
data[count] = val;
count++;
}
//inserts value at index
template<class T>
void ArrayList<T>::insert(T val, int index) {
if (!isValid(index)) return;
//if index is greater than current size, expand
while (index >= realSize || count >= realSize) {
expand();
}
//shift values before index
for (int i = count; i >= index; i--) {
T val = data[i];
data[i + 1] = data[i];
}
data[index] = val;
count++;
}
//return value at index
template<class T>
T ArrayList<T>::get(int index) {
if (!isValid(index)) return 0;
return data[index];
}
template<class T>
int ArrayList<T>::size() {
return count;
}
template<class T>
void ArrayList<T>::expand() {
//double array size
realSize = realSize * 2;
T* newData = new T[realSize];
//replace data
for (int i = 0; i < count; i++) {
newData[i] = data[i];
}
delete[]data; //<--ERROR OCCURS HERE
data = newData;
}
這是一些會導致錯誤的代碼
ArrayList<int>* list = new ArrayList<int>();
list->add(1);
list->add(5);
list->insert(2, 1);
list->insert(3, 2);
list->insert(4, 3); //<---ERROR OCCURS HERE
錯誤是一個消息框,內容為
調試錯誤!
程序:...ommunity\\Common7\\IDE\\Extensions\\TestPlatorm\\testhost.x86.exe
檢測到堆損壞:在 0x05D69BC0 處的正常塊 (#296) 之后
CRT 檢測到應用程序在堆緩沖區結束后寫入內存。
為什么在調用expand方法的時候偶爾會報錯? 據我所知,調用 expand() 時數組按預期順序排列(在我的示例中,它是{1, 2, 3, 5}
)。
問題出在insert
方法中。 當您向上復制現有元素以為新元素騰出空間時,從元素count
開始,將data[count]
向上復制一個槽到data[count + 1]
。 但是,沒有元素存儲在data[count]
,在正確的情況下,對data[count + 1]
訪問將超過為data
分配的空間。
這些情況發生在第二次insert
調用中。 count
為 3, realsize
為 4, index
為 2,因此不會發生擴展。 然后,您的 for 循環將分配data[count + 1] = data[count]
,即data[4] = data[3]
。 由於 data 只有 4 個元素的空間,因此寫入data[4]
破壞超過分配空間末尾的數據,這會在稍后的內存操作中檢測到(在這種情況下,當分配的空間通過調用delete
釋放時) .
解決方案是在int i = count - 1
處開始循環,或者在條件中將其遞減:
for (int i = count; --i >= index; )
無關, T val = data[i];
聲明沒有任何用處,可以刪除。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.