簡體   English   中英

如何解釋動態分配二維數組時有時會發生分段錯誤?

[英]How to explain Segmentation fault sometimes happening when dynamically allocating 2D array?

我想要一個函數,用列和行初始化簡單的網格(二維數組),然后每個位置(單元格)就是結構的大小。

我找到了一個解決方案,可以在 main 函數中完成此操作,但是在任何其他函數中完成時,在運行中途后,它在打印網格之前因分段錯誤而崩潰(與上一段不同)。

但是,如果在初始化部分后直接添加打印Grid,則之后代碼可以正常工作,所有故障都會消失。

我懷疑 main 現在沒有初始化 Position 數組,但我將它作為指針傳遞,所以我做錯了什么?

下面的代碼分為兩部分。 第一個有分段錯誤,第二個沒有。 唯一的區別是在第二部分中,用於打印網格的 for 循環在初始化二維數組的函數內部。

//SEGMENTATION FAULT

void CreateMap (struct GameGrid *Position, int &Dim_x, int &Dim_y)
{
    cout << "Lets create the game map." << endl;
    cout << "Enter number of Columns: ";
    cin >> Dim_x;
    cout << "Enter number of Rows: ";
    cin >> Dim_y;

    Position = new GameGrid[Dim_x * Dim_y];
}

int main()
{
    struct GameGrid *Position = NULL;
    int Dim_x;
    int Dim_y;

    CreateMap(Position, Dim_x, Dim_y);

    for (int y=0; y < Dim_y; y++)
    {
        cout << setw (20);

        for (int x=0; x < Dim_x; x++)
        {
            cout << Position[x*Dim_y + y].Element;
            cout << char(32);
        }
        cout << endl;
    }

    delete[] Position;
    return 0;
}

//NO FAULTS

void CreateMap (struct GameGrid *Position, int &Dim_x, int &Dim_y)
{
    cout << "Lets create the game map." << endl;
    cout << "Enter number of Columns: ";
    cin >> Dim_x;
    cout << "Enter number of Rows: ";
    cin >> Dim_y;

    Position = new GameGrid[Dim_x * Dim_y]

    for (int y=0; y < Dim_y; y++)
    {
        cout << setw (20);

        for (int x=0; x < Dim_x; x++)
        {
            cout << Position[x*Dim_y + y].Element;
            cout << char(32);
        }
        cout << endl;
    }
}

int main()
{
    struct GameGrid *Position = NULL;
    int Dim_x;
    int Dim_y;

    CreateMap(Position, Dim_x, Dim_y);

    delete[] Position;
    return 0;
}

對於維度 Dim_x=6 和 Dim_y=6(由最終用戶選擇),網格應該看起來像這樣。

A A A A A A
A A A A A A
A A A A A A
A A A A A A
A A A A A A
A A A A A A

同樣,當打印網格兩次(一次在函數 CreateMap 中,一次在 main 中)時,它會兩次打印它們,然后凍結 10 秒並死亡。

在您的CreateMap函數中:

void CreateMap (struct GameGrid *Position, int &Dim_x, int &Dim_y)
{
    // ...    
    Position = new GameGrid[Dim_x * Dim_y];
}

這僅修改Position局部變量,它不會改變提供給該參數的調用者的值。

你需要的是重新工作:

GameGrid *CreateMap(const int Dim_x, const int Dim_y)
{
    // ...    
    return new GameGrid[Dim_x * Dim_y];
}

返回一個您可以捕獲的值的地方:

int main()
{
  int x, y;
  cout << "Lets create the game map." << endl;
  cout << "Enter number of Columns: ";
  cin >> x;
  cout << "Enter number of Rows: ";
  cin >> y;

  GameGrid *Position = CreateMap(x, y);
  // ...
}

在這些功能之外執行所有輸入/輸出。 記住你的SOLID 原則,給這個功能一份工作,一份工作。 輸入和分配是兩個工作。

更好的是:創建一個構造函數而不是這些CreateX函數。 這是 C++,您可以充分利用它。

一如既往:

每當您遇到奇怪的行為時,請在調試器中單步調試您的代碼,以查看執行時各種變量的值。

盡管您使用指針作為參數,但您仍然是按值傳遞。

當嘗試通過引用傳遞時,指針本身沒有改變,但它指向的地址處的對象被更新。

因此,要更新指針,您需要一個指向該指針的指針或一個對指針的引用。 否則,通常正如已回答的那樣,返回用於返回更新的指針。

暫無
暫無

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

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