C 中的段错误(在 for 循环中间)
Segfault in C (during middle of for loops)
我正在尝试通过编写记忆型纸牌游戏来练习C。该游戏由 gcc 在 ARMv8 上编译。用户在参数行中输入一个数字“users_N”,然后创建一副纸牌大小:2N x 2N。
程序在数字为 1 或 2 时运行良好。但如果数字为 3 或更大,我在尝试初始化电路板时遇到分段错误。我认为这意味着它是堆栈溢出,但我在我的 SSH 上将堆栈大小增加到无限,但问题没有解决。我不认为这是指针或尝试越界访问数组的问题,因为它运行得很好,直到将 10 张卡片添加到数组中。
打印语句只是为了确定段错误发生的确切时间。See image of for loop segfault
编辑:添加更多上下文...我知道它有点乱,抱歉!
int main(int argc, char *argv[]) {
if (argc < 3){ //Checking user's command line input.
printf("Missing argument. Exiting... \n");
return 0;
}
users_N = atoi(argv[2]);
srand(time(NULL)); //Initialize random number generator.
int ***board = (int ***)malloc(2 * users_N * sizeof(int)); //Dynamic array to store the board values
for (int i = 0; i < 2 * users_N; i++){
board[i] = (int **)malloc(2 * users_N * sizeof(int)); /*Array of pointers (rows) filled with
an array (columns). */
for (int j = 0; j < 2 * users_N; j++){
board[i][j] = (int *)malloc(2 * sizeof(int)); //3rd dimension to show/hide cards.
}
}
initialize(board);
}
/*
* Function initialize sets up the board. It takes the 3D board array. A card deck is created the
* size of 2N^2, then shuffled and added to the board. The 3rd dimension is initialized
* completely to 1, so all cards are shown. There is no return.
*/
void initialize(int*** board){
int* cards = (int *)malloc(2 * users_N * users_N * sizeof(int)); //Create an array of cards.
printf("Cards created\n");
for (int c = 0; c < (2 * users_N * users_N); c++){
printf("card: %d\n",c);
cards[c]=c;
}
int half = 0;
while (half < 2){ //Divide up into 2 halves of the board, to repeat shuffle and card placement.
shuffle(cards);
int cardsNum = 0;
for (int j = 0; j < users_N; j++){ //For each row in the current half:
printf("\n row = %d ", j);
for (int k = 0; k < (users_N * 2); k++){ //For each column:
printf("col = %d ",k);
board[j + (half * users_N)][k][0] = cards[cardsNum]; /* Assign appropriate
card to each board
position. */
printf("set to: %d ", board[j + (half * users_N)][k][0]);
board[j + (half * users_N)][k][1] = 1;
cardsNum++;
printf("Card num: %d \n", cardsNum);
}
}
half++; //Moves to next half to repeat.
}
}
/*
* Function shuffle takes the array of cards as a parameter. It will then randomly mix array.
* Numbers are not repeated and will not exceed 2N*N-1. No return values.
*/
void shuffle(int *cards){
int j;
for (int k = 0; k < (2 * users_N * users_N) - 2; k++){
j = randomNum(k, (2 * users_N * users_N) - 1); //Assign a random number between k and 2N*N-1.
swap(cards, k, j);
printf("cards swapped: %d,%d\n",k,j);
}
}
/*
* Function swap takes the array of cards, two index integers. The index integers indicate the positions of
* the elements (cards) to switch. No return values.
*/
void swap(int *cards, int i, int j){
int temp = cards[i]; //Value of position i stored in temp.
cards[i] = cards[j]; //value of card j assigned to card i.
cards[j] = temp; //Value of temp assigned to card j.
}
你的板子分配错误:
int ***board = (int ***)malloc(2 * users_N * sizeof(int));
^^^^^^^^^^^
wrong size
for (int i = 0; i < 2 * users_N; i++){
board[i] = (int **)malloc(2 * users_N * sizeof(int));
^^^^^^^^^^^
wrong size
...
}
当您将 board
作为 int ***
时,您不希望在第一次分配期间使用 int
的大小。您想要 int **
的大小。喜欢
int ***board = malloc(2 * users_N * sizeof(int**));
更好的方法是使用变量名——例如:
int ***board = malloc(2 * users_N * sizeof *board);
^^^^^^
Better approach
to get correct size
下一个也一样malloc
我正在尝试通过编写记忆型纸牌游戏来练习C。该游戏由 gcc 在 ARMv8 上编译。用户在参数行中输入一个数字“users_N”,然后创建一副纸牌大小:2N x 2N。
程序在数字为 1 或 2 时运行良好。但如果数字为 3 或更大,我在尝试初始化电路板时遇到分段错误。我认为这意味着它是堆栈溢出,但我在我的 SSH 上将堆栈大小增加到无限,但问题没有解决。我不认为这是指针或尝试越界访问数组的问题,因为它运行得很好,直到将 10 张卡片添加到数组中。
打印语句只是为了确定段错误发生的确切时间。See image of for loop segfault
编辑:添加更多上下文...我知道它有点乱,抱歉!
int main(int argc, char *argv[]) {
if (argc < 3){ //Checking user's command line input.
printf("Missing argument. Exiting... \n");
return 0;
}
users_N = atoi(argv[2]);
srand(time(NULL)); //Initialize random number generator.
int ***board = (int ***)malloc(2 * users_N * sizeof(int)); //Dynamic array to store the board values
for (int i = 0; i < 2 * users_N; i++){
board[i] = (int **)malloc(2 * users_N * sizeof(int)); /*Array of pointers (rows) filled with
an array (columns). */
for (int j = 0; j < 2 * users_N; j++){
board[i][j] = (int *)malloc(2 * sizeof(int)); //3rd dimension to show/hide cards.
}
}
initialize(board);
}
/*
* Function initialize sets up the board. It takes the 3D board array. A card deck is created the
* size of 2N^2, then shuffled and added to the board. The 3rd dimension is initialized
* completely to 1, so all cards are shown. There is no return.
*/
void initialize(int*** board){
int* cards = (int *)malloc(2 * users_N * users_N * sizeof(int)); //Create an array of cards.
printf("Cards created\n");
for (int c = 0; c < (2 * users_N * users_N); c++){
printf("card: %d\n",c);
cards[c]=c;
}
int half = 0;
while (half < 2){ //Divide up into 2 halves of the board, to repeat shuffle and card placement.
shuffle(cards);
int cardsNum = 0;
for (int j = 0; j < users_N; j++){ //For each row in the current half:
printf("\n row = %d ", j);
for (int k = 0; k < (users_N * 2); k++){ //For each column:
printf("col = %d ",k);
board[j + (half * users_N)][k][0] = cards[cardsNum]; /* Assign appropriate
card to each board
position. */
printf("set to: %d ", board[j + (half * users_N)][k][0]);
board[j + (half * users_N)][k][1] = 1;
cardsNum++;
printf("Card num: %d \n", cardsNum);
}
}
half++; //Moves to next half to repeat.
}
}
/*
* Function shuffle takes the array of cards as a parameter. It will then randomly mix array.
* Numbers are not repeated and will not exceed 2N*N-1. No return values.
*/
void shuffle(int *cards){
int j;
for (int k = 0; k < (2 * users_N * users_N) - 2; k++){
j = randomNum(k, (2 * users_N * users_N) - 1); //Assign a random number between k and 2N*N-1.
swap(cards, k, j);
printf("cards swapped: %d,%d\n",k,j);
}
}
/*
* Function swap takes the array of cards, two index integers. The index integers indicate the positions of
* the elements (cards) to switch. No return values.
*/
void swap(int *cards, int i, int j){
int temp = cards[i]; //Value of position i stored in temp.
cards[i] = cards[j]; //value of card j assigned to card i.
cards[j] = temp; //Value of temp assigned to card j.
}
你的板子分配错误:
int ***board = (int ***)malloc(2 * users_N * sizeof(int));
^^^^^^^^^^^
wrong size
for (int i = 0; i < 2 * users_N; i++){
board[i] = (int **)malloc(2 * users_N * sizeof(int));
^^^^^^^^^^^
wrong size
...
}
当您将 board
作为 int ***
时,您不希望在第一次分配期间使用 int
的大小。您想要 int **
的大小。喜欢
int ***board = malloc(2 * users_N * sizeof(int**));
更好的方法是使用变量名——例如:
int ***board = malloc(2 * users_N * sizeof *board);
^^^^^^
Better approach
to get correct size
下一个也一样malloc