簡體   English   中英

C ++ 11錯誤-當我嘗試動態增加數組大小時,此錯誤是什么意思?

[英]C++11 Error - What does this error mean when I try to dynamically increase the size of an array?

我正在使用此算法來動態增加數組的大小:

void resize(int* oldArray, int* capacity) {
    *capacity = *capacity * 2;
    int* new_array = new int[*capacity];
    for (int i = 0; i < *capacity/2; i++) {
        new_array[i] = oldArray[i];
    }
    delete[] oldArray;
    oldArray = new_array;
}

但是,當我構建並運行此算法時,出現以下錯誤:

r3(21751,0x7fff8d76e340)malloc: *對象0x7f8ca5c026c0錯誤:未分配釋放的指針*在malloc_error_break中設置一個斷點以調試中止陷阱:6

另外,這是我正在使用的主要功能:

int main(int argc, char* argv[]) {
    if (argc != 2) {
        return -1;
    }

    std::ifstream inFile(argv[1]);
    int capacity = 10;
    int* num_array = new int[capacity];
    int num_elements = 0;

    if (inFile.is_open()) {
        std::string line;
        while (!inFile.eof()) {
            getline(inFile,line);
            if (num_elements == capacity) {
                resize(num_array,&capacity);
            }
            int num = stoi(line);
            num_array[num_elements++] = num;
        }

        for (int i = 0; i < num_elements; i++) {
            std::cout<<num_array[i]<<std::endl;
        }
    }
}

誰能告訴我為什么會這樣? 謝謝!

這意味着您是“ C +程序員”,那個奇怪的人似乎還沒有完全脫離C :-)

諸如使用malloc/free (甚至在當今的智能指針中甚至是new/delete ),原始數組而不是標准集合,為<algorithms>找到的東西滾動自己的代碼,使用printf而不是流等東西。 ,這些是您通常應該避免的事情。

我建議您考慮使用std::vector如果您想要可調整大小的數組,它是語言本身的一部分,並且已經過充分而真實的測試(a)

有關調整數組大小和添加新元素的所有工作都可以用一個簡單的替換:

myVector.push_back(myElement);

(a)是的,我很清楚它不能回答您的特定問題,但是,例如,用匯編器編寫會計軟件包,使用面向對象的COBOL開發新的操作系統或使用Pascal :-)進行任何操作 ,有時正確的答案是“不要那樣做”。

如果您確實堅持要成為“ C +程序員”,那么您至少應該了解,要在函數中進行更改並將效果返回給調用方的所有內容都應通過引用傳遞。 在這種情況下,這是兩個指針可變容量(也沒有必要用C的丑惡基於指針的傳遞通過引用弄虛作假在C ++中):

#include <algorithm>
:
void resize(int *&oldArray, int &capacity) {
    capacity *= 2;
    int newArray = new int[capacity];
    std::copy(oldArray, oldArray + capacity / 2, newArray);
    delete[] oldArray;
    oldArray = newArray;
}

您會在那里看到一些改進,特別是:

  • 正確的變量傳遞參考。
  • 使用std::copy復制元素,而不是編寫自己的循環。
  • 一致的命名(並非絕對必要,但對滿足我的CDO (b)有用)。

(b)強迫症,但以正確的命令:-)

您需要一個&

// ...............V
void resize(int * & oldArray, int* capacity) {
*capacity = *capacity * 2;
int* new_array = new int[*capacity];
for (int i = 0; i < *capacity/2; i++) {
    new_array[i] = oldArray[i];
}
delete[] oldArray;
oldArray = new_array;
}

如果您傳遞一個指向resize()的指針,而沒有一個&來通過引用傳遞它,那么您將通過copy傳遞它。 因此,您可以更改指定整數的值,但不能更改指針本身的值。

int* num_array = new int[capacity];

您動態分配一個區域,第一個。

第一次撥打

resize(num_array,&capacity);

該區域已銷毀(在resize() ),並且分配了第二個區域,但丟失了,因為在main()num_array保持第一個區域的值。

隨着第二個電話

resize(num_array,&capacity);

第一個分配的區域被第二次刪除。

崩潰!

傳遞oldArray作為參考,新分配區域的值將分配給main()num_array變量。

如果要為此指針分配新的內存,則應傳遞指針num_array引用

您應該將void resize(int* oldArray, int* capacity)更改為void resize(int* & oldArray, int* capacity)

其背后的原因是,當您通過傳遞參數num_array調用函數resize時,僅創建了一個名為oldArray新指針類型變量num_array在函數體內使用與num_array相同的值對其進行了初始化。

因此,當您新建一個內存時,您只是為該新變量 oldArray 分配了內存,而不為參數num_array 分配了內存 但是,當你調用delete[] oldArray ,它實際上是釋放你已經為分配的內存num_array因為oldArray具有相同的值num_array這里。

要解決此問題,您只需傳遞num_array的引用num_array

暫無
暫無

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

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