[英]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.