簡體   English   中英

動態二維數組。 為什么會出現分段錯誤?

[英]Dynamic 2D array. Why is segmentation fault?

我的問題很簡單。 看看這段代碼。

#include <iostream>
using namespace std;

int main() {
    int **arr = new int*[3];
    cout << "arr : " << arr << endl;   // It will display address, may be 0xffc1e...
    cout << "*arr : " << *arr << endl;    // will be just 0(zero), may be default value
    cout << "**arr : " << **arr << endl;    // it will display nothing,  and after that program terminates
    cout << "Program completed." << endl;    // This will not display because program terminated
} 

由於檢索 **arr,該程序終止。 如果我們去掉行,則是 **arr。 程序將正常完成並寫入“程序完成”。 gdb 說這是分段錯誤。 這樣這段代碼就可以工作了。

#include <iostream>
using namespace std;

int main() {
    int **arr = new int*[3];
    cout << "arr : " << arr << endl;   // It will display address, may be 0xffc1e...
    cout << "*arr : " << *arr << endl;    // will be just 0(zero), may be default value
    cout << "Program completed." << endl;    // This at last will be displayed
} 

所以沒有行 where is **arr,代碼正常工作。 為什么???

您已經默認初始化了動態數組。 它是一個指針數組。 默認初始化指針具有不確定的值。 讀取不確定值的行為是未定義的。

為什么???

因為程序的行為是未定義的。

未定義的行為意味着程序的行為沒有任何保證。 就語言而言,該程序可能:

  • 產生您期望的輸出。
  • 產生出乎意料的輸出。
  • 生成您想要生成的輸出。
  • 產生一些你不想要的輸出。
  • 根本不產生輸出。
  • 碰撞
  • 不崩潰
  • 在另一個系統上表現不同。
  • 在同一個系統上表現不同。
  • 調試時表現不同。
  • 只有在度假時才表現得不同。
  • 出於任何可能的原因表現不同。
  • 似乎毫無理由地表現出不同的行為。
  • 總是表現得一樣
  • 不要那樣做。
  • 有任何行為。

應避免未定義的行為。

您已經為 3 個int*分配了空間,但是您還沒有初始化它們中的任何一個,因此像*arr一樣讀取它們會使您的程序具有未定義的行為。

*arr返回的地址(如果有的話)讀取,就像**arr一樣,也會使其具有未定義的行為 - 並且經常導致崩潰(如果幸運的話)。

你需要做的int*小號一點東西。 初始化指針。 另請注意,對於每個new您只需要一個delete ,對於每個new[]您只需要一個delete[]

一些例子:

int main() {
    int** arr = new int*[3];

    arr[0] = new int[5];  // an array of 5 int
    arr[1] = new int[10]; // 10...
    arr[2] = new int[20]; // 20...

    // use arr

    // cleanup
    delete[] arr[2];
    delete[] arr[1];
    delete[] arr[0];

    delete[] arr;
} 

請注意,分配的內存仍未初始化,因此在將數據存儲在其中之前不應從中讀取。

如果發生任何事情(如異常),清理工作很容易被遺忘或跳過。 為此,有智能指針。 它們一開始可能看起來很尷尬,但會為您省去很多麻煩。

#include <iostream>
#include <memory>
int main() {
    std::unique_ptr<std::unique_ptr<int[]>[]> arr = 
                                         std::make_unique<std::unique_ptr<int[]>[]>(3);

    arr[0] = std::make_unique<int[]>(5);
    arr[1] = std::make_unique<int[]>(10);
    arr[2] = std::make_unique<int[]>(20);

    // using arr
    std::cout << arr[0][4] << "\n";  // Using make_unique also default initialized the 
    std::cout << arr[1][9] << "\n";  // elements in the arrays, so reading from them is 
    std::cout << arr[2][19] << "\n"; // fine.

} // all arrays held by smart pointers are automatically deleted when arr
  // goes out of scope

暫無
暫無

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

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