我正在尝试通过编写内存类型的纸牌游戏来练习C。游戏由gcc在ARMv8上编译。用户输入一个数字"0";用户_ N";在自变量行中,创建了一块大小为2N x 2N的卡片。
当数字为1或2时,程序运行得很好。但如果它是3或更大,我在尝试初始化电路板时会遇到分段错误。我以为这意味着这是一个堆栈溢出,但我在SSH上将堆栈大小增加到了无限制,问题没有得到解决。我不认为指针或试图越界访问数组有问题,因为在向数组添加10张牌之前,它运行得很好。
print语句只是用来确定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 createdn");
for (int c = 0; c < (2 * users_N * users_N); c++){
printf("card: %dn",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,%dn",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