Использование указателей для изменения матрицы
В нашем c курсе учитель дал нам мини-проект по созданию игры "Реверси". У меня проблемы со сборкой доски.
#define Size 8
int main()
{
char Board[Size][Size] = { {" "} };
resetBoard(Board);
printBoard(Board);
printf("\n");
getch();
}
void resetBoard(int** board)
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
*(board + (i * Size + j)) = 'x';
}
}
}
void printBoard(int board[Size][Size])
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
printf("%c", board[i][j]);
printf(" ");
}
printf("\n");
}
}
Я проверил программу, и программа получает:
Ошибка проверки времени выполнения #2 - стек вокруг переменной 'Board' был поврежден
когда он меняет первый X в третьем ряду. Например, если я запускаю программу до конца 2-й строки (16), я не получу эту ошибку.
4 ответа
Я думаю, что могут быть проблемы с инициализацией вашей доски как типа char и работой с указателями и массивом типа int в ваших функциях. Char имеет размер 1 байт, а int имеет больший размер в зависимости от платформы (чаще всего 4 байта). Это вызовет проблемы с памятью при манипуляциях и зацикливании вашего массива.
В вашем случае, похоже, что вы перебрали всю выделенную память после 2 строк, потому что вы использовали указатели типа int. Int в вашем случае, вероятно, в 4 раза больше, чем char, в результате чего вся ваша структура данных типа char в 4 раза быстрее, чем вы ожидали.
Вы получили кучу ошибок в вашем коде. Эта версия должна работать.
//Use all capitals for defines
#define BOARD_SIZE 8
//Just reset the whole array to spaces.. No need to traverse byte by byte.
void resetBoard(char* board) {
//memset version
//memset(board, ' ', (BOARD_SIZE*BOARD_SIZE)*sizeof(char));
//non memset version
for (int i=0; i<(BOARD_SIZE*BOARD_SIZE); i++) *board++='x';
}
void printBoard(char *board) {
for (int i = 0; i < BOARD_SIZE; i++){
for (int j = 0; j < BOARD_SIZE; j++){
//Access the 2D array like this (y * width of array + x)
printf("%c", board[i*BOARD_SIZE+j]);
printf(" ");
}
printf("\n");
}
}
//Don't start a name using capitals.. Later when you program c++ or similar you will understand :-)
int main()
{
//This is a more dynamic memory model and is not allocated on the stack.. (free when done!!)
char *board=(char*)malloc(BOARD_SIZE*BOARD_SIZE);
//there are several ways of working with arrays.. No need to complicate stuff if not needed.
//Just point out the first byte of the array.. (See the methods takes a char pointer and that is whet's passed the methods)
if (board) {
resetBoard(board);
//Test to see if it works
board[1*BOARD_SIZE+2]='0';
printBoard(board);
free(board);
} else {
printf("Out of memory!\n");
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Ниже указатель версии моего предыдущего предложения:
#include<stdio.h>
#include<stdlib.h>
#define Size 8
void resetBoard(char *board, int size);
void printBoard(char *board, int size);
int main()
{
char *Board = (char *)malloc(Size*Size*sizeof(char));
resetBoard(Board, Size);
printBoard(Board, Size);
printf("\n");
free(Board);
return 0;
}
void resetBoard(char *board, int size)
{
for (size_t i = 0; i < size; i++)
{
for (size_t j = 0; j < size; j++)
{
*(board +i*size + j) = 'x';
}
}
}
void printBoard(char *board, int size)
{
for (size_t i = 0; i < size; i++)
{
for (size_t j = 0; j < size; j++)
{
printf("%c ", *(board +i*size + j));
}
printf("\n");
}
}
Компиляция (на моей машине) выглядит снова, как:
gcc -std=c11 -Wall reversi.c -o a.out
и исполнение дает:
./a.out
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
@RotemHeinig. Ваш код имеет много недостатков. Ниже приведен пример переформатирования вашего примера. Может быть, это даст вам представление о том, как улучшить работу:
#include<stdio.h>
#define Size 8
void resetBoard(char board[][Size]);
void printBoard(char board[][Size]);
int main()
{
char Board[Size][Size];
resetBoard(Board);
printBoard(Board);
printf("\n");
return 0;
}
void resetBoard(char board[][Size])
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
board[i][j] = 'x';
}
}
}
void printBoard(char board[][Size])
{
for (size_t i = 0; i < Size; i++)
{
for (size_t j = 0; j < Size; j++)
{
printf("%c ", board[i][j]);
printf(" ");
}
printf("\n");
}
}
Компиляция этого кода с помощью gcc на моей машине выглядит так:
gcc -std=c11 -Wall reversi.c -o a.out
И исполнение дает:
./a.out
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
x x x x x x x x
Я надеюсь, что вы найдете здесь вдохновение.