2015-03-07 3 views
1

Итак, у меня есть то, что я думаю, вопрос о нобе. Извините за это заранее, и для грамматики, поскольку английский не является моим основным языком.Инициализировать структуру с помощью malloc в C

Так что я должен сделать игру шашек. У меня есть некоторые-структуру, определенную

struct game { 
int **board; 
int xsize, ysize; 

struct move *moves; 
int cur_player; 
}; 

struct coord { 
int x, y; 
}; 

struct move_seq { 
struct move_seq *next; 
struct coord c_old; 
struct coord c_new; 
int piece_value; 
struct coord piece_taken; 
int old_orig; 
}; 

struct move { 
struct move *next; 
struct move_seq *seq; 
}; 

И я должен инициализировать STRUCT игру Жека в fonction

struct game *new_game(int xsize, int ysize) 

Итак, вот моя проблема. Я теперь называю new_game всегда с 10 и 10 значениями для xsize ysize. Затем я инициализирую настольную игру, которую я хочу назначить позже.

int black = 1; 
int white = 5; 
int **board; 
int i; 
int j; 
int k; 
for(i=0;i<xsize;i++) 
{ 
    for(j=0;j<ysize;j++) 
    { 
     if(i<(xsize/2) && j<(ysize/2) && (i+j)%2!=0) 
     { 
      board[i][j] = black; 
     } 
     else if(i>(xsize/2) && j>(ysize/2) && (i+j)%2!=0) 
     { 
      board[i][j] = white; 
     } 
     else board[i][j] = 0; 
    } 
} 
struct game *new = malloc (sizeof(struct game *)); 
if (new == NULL) return NULL; 

Итак, моя проблема в этом. У меня просто есть проблема с сегментацией, что бы я ни делал с моей новой структурой.

Я попытался присвоить new-> xsize = xsize и то же самое с ysize. Я делаю malloc для доски и движения структуры, как я научился делать, но я продолжал получать эту ошибку Segmentation Fault.

Итак, вот мой реальный вопрос: как правильно назначить и правильно инициализировать структуру? Должен ли я сделать malloc для каждого из членов структурированной игры? (Я тоже это пробовал, но без успеха ...)

Мне не обязательно нужен только ответ, я бы предпочел действительно понять, что я должен делать в этом случае и вообще делать меньше ошибок в будущем.

Заранее за вашу помощь.

Удачного дня.

+1

'int ** board;' Этот указатель на указатель никогда не инициализируется; он может указывать на любой указатель в любом месте. – wildplasser

+0

«новое» - это зарезервированное слово в любом компиляторе, способном обрабатывать код на C++, даже несмотря на то, что код имеет значение C. Поэтому настоятельно рекомендуем изменить имя из «нового» на нечто более значимое, что не является зарезервированным словом – user3629249

ответ

0

В дополнение к исправлению ошибки Михаэля, я также задаюсь вопросом о борту: он не выделен, но вы пишете ему. Я думаю, что это должно быть так:

struct game *new_game(int xsize, int ysize) 
{ 
    int black = 1; 
    int white = 5; 
    int i; 
    int j; 

    struct game *new = malloc (sizeof(struct game)); 
    if (new == NULL) return NULL; 
    game->xsize= xsize; 
    game->ysize= ysize; 
    game->board= malloc(xsize*ysize*sizeof(int)); 

    for(i=0;i<xsize;i++) 
    { 
     for(j=0;j<ysize;j++) 
     { 
      if(i<(xsize/2) && j<(ysize/2) && (i+j)%2!=0) 
      { 
       game->board[i*xsize+j] = black; 
      } 
      else if(i>(xsize/2) && j>(ysize/2) && (i+j)%2!=0) 
      { 
       game->board[i*xsize+j] = white; 
      } 
      else game->board[i*xsize+j] = 0; 
     } 
    } 
    return (game); 
} 

Отметим также индексация массива: компилятор не знает, динамический размер строки, так что вы должны сделать это самостоятельно.

+0

Когда используется в других местах я получаю новый Seg Fault с доской. Правильно ли он распределен так, как вы показали мне? Когда я искал, как распределять память для 2D-массива, я нашел другой путь. Как и я сделал это с циклом для выделения памяти для каждой строки. И еще раз спасибо :) – Lusheez

+0

Мое распределение платы и индексация платы правильные. Когда вы делаете new-> board = malloc (xsize * sizeof (int **)); вы выделяете место для одной строки указателей (которые, как оказалось, имеют размер int), но вы не выделяете всю доску. Подумайте: сколько квадратов имеет доску? И выделите столько памяти. –

+0

Об индексировании: вы выделили один кусок линейной памяти и должны поместить в него плату, как строки (x) за другим. Затем, чтобы перейти к третьей строке, 2-й столбец, перейдите 2 * xsize вправо, затем добавьте 1 для столбца (индексы начинаются с нуля). Примечание. Индексирование в качестве платы [i] [j] работает только в том случае, если компилятор знает строку (которая этого не делает). –

4

Это происходит потому, что вы выделили место для указателя на ваш struct. Что вам нужно сделать, это передать его на весь размер его:

struct game *new = malloc (sizeof(struct game)); 

Edit: Не вводить в заблуждение возвращаемого значения таНос, так как она возвращает указатель на выделенное пространство, поэтому его должен быть struct game *new как есть.

0

Хорошо, спасибо! Я думаю, это помогло немного, так как многие предупреждения были сняты. Но я продолжаю получать Seg Fault. Вот мой окончательный код new_game:

struct game *new = malloc (sizeof(struct game)); 
if (new == NULL) return NULL; 
new->xsize = xsize; 
new->ysize = ysize; 
new->cur_player = PLAYER_WHITE; 
new->moves = malloc(sizeof(struct move)); 
if(new->moves == NULL) 
{ 
    free(new->moves); 
    return NULL; 
} 
new->moves = NULL; 
new->board = malloc(xsize*sizeof(int **)); 
if(new->board == NULL) 
{ 
    free(new->board); 
    return NULL; 
} 
for(k=0;k<xsize;k++) 
{ 
    new->board[k] = malloc(ysize*sizeof(int*)); 
} 
new->board = board; 

У меня есть немного сомнения, с тем, что я делаю с Нью-> двигается = таНос (SizeOf (структура ход)); и то же самое с доской.

Извините, что задавали такие глупые вопросы, но большое спасибо за быстрые ответы!

+0

О, я отправил слишком быстро и не видел ответа Павла! Извините, я буду работать с этим и дам вам знать. Черт, это сообщество быстро! :) – Lusheez

+0

код, который проверяет результат malloc для «new-> move», неверен, что нужно быть свободным, это «новый», потому что он был успешным, а не malloc для ходов, который потерпел неудачу – user3629249

+0

относительно эта строка: 'new-> board = malloc (xsize * sizeof (int **));' board - это int **, но отдельные записи - это только int *, поэтому в этой строке должно быть значение sizeof (int *) ': new-> board [k] = malloc (ysize * sizeof (int *)); ' каждый (столбец) является массивом int не любого массива из int *, поэтому он должен быть «sizeof (int)». В общем случае переменная int ** выделяется сначала для количества указателей на строки, которые затем выделяются для каждой строки. Код выделяет сначала для числа столбцов, а затем для количества строк в каждом столбце – user3629249

0

Ok! Думаю, я все ближе.Мой код для платы выглядит следующим образом:

int black = 1; 
int white = 5; 
int i; 
int j; 
int k; 
struct game *new_game = malloc (sizeof(struct game)); 
if (new_game == NULL) return NULL; 
new_game->board = malloc(xsize*ysize*sizeof(int *)); 
if(new_game->board == NULL) 
{ 
    free(new_game); 
    return NULL; 
} 
for(k=0;k<xsize;k++) 
{ 
    new_game->board[k]=malloc(ysize*sizeof(int)); 
    if(new_game->board[k] == NULL) 
    { 
     free(new_game); 
     return NULL; 
    } 
} 
for(i=0;i<xsize;i++) 
{ 
    for(j=0;j<ysize;j++) 
    { 
     if(j<(ysize/2)-1 && (i+j)%2!=0) 
     { 
      new_game->board[j][i] = black; 
     } 
     else if(j>(ysize/2) && (i+j)%2!=0) 
     { 
      new_game->board[j][i] = white; 
     } 
     else 
     { 
      new_game->board[j][i] = 0 
     } 
    } 
} 

Для таНоса совета я был вдохновлен этим С.О. сообщений: How do I work with dynamic multi-dimensional arrays in C? Но я получил ошибку сегментации при доступе к второй линии платы. Я могу распечатать первую строку без каких-либо проблем, но, видимо, памяти нет. Но моя строка new_game-> board [k] = malloc (ysize * sizeof (int)); должен ли это делать?

+0

ОК, поэтому не было очевидной проблемы с моим кодом, я просто обращался к массиву неправильно. Kinda dumb error. Спасибо всем! – Lusheez

Смежные вопросы