Правильное использование malloc / realloc для typedef struct - PullRequest
0 голосов
/ 27 мая 2018

У меня полностью функциональная программа *, но у меня есть вопрос о выделении памяти, потому что что-то для меня все еще неясно.(* полностью функциональный означает, что у меня есть результаты, которые я хочу получить, что также может быть удачей).

typedef struct Field {
    long index;
    long x;
    long y;
    struct Cell *N;
    struct Cell *S;
    struct Cell *E;
    struct Cell *W;
    int count;
    bool used;
} Field;

typedef struct Construct {
    Field *fs1;
    Field *fs2;
} Construct;

Field *fields;
long countFields = 1;

Construct *constructs;
long countStructs = 1;

Есть две структуры, одна называется Клетка, другая - Камень, Клетка имеет координаты,индекс, число, бул и указатели на четыре другие ячейки.Камень просто имеет два указателя на ячейки.Оба имеют определение типа для одного и того же имени, просто добавляя Td.

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

Вот как я это узнал. Полагаю, a также может заменить "CellTd" на "struct Cell" и т. Д.,x - это просто фактор, который говорит о моей проблеме.

Моя текущая проблема в том, что я не уверен, что это точно, потому что у меня разные результаты при увеличении x.Поэтому, когда я работаю с ним, иногда нет серьезного указателя на некоторые элементы, когда коэффициент x равен 1. Я использую x = 50, тогда все работает, но это не должно быть, как это работает.(Просто чтобы сказать, что, конечно, и countStones, и countCells создаются в количестве элементов в массиве ...)

Я делаю что-то не так с перераспределением?

1 Ответ

0 голосов
/ 27 мая 2018

Прежде всего, если вы хотите выделить массив вещей, используйте calloc.Он проверяет переполнения при умножении и хорошо инициализирует все ваши значения с нулями.

Во-вторых, убедитесь, что вы проверяете свои calloc и realloc вызовы на успех.Если они потерпят неудачу, они вернут нулевые указатели.Затем вы можете использовать perror, чтобы определить, почему они потерпели неудачу, распечатать хорошие сообщения об ошибках и выйти.

Для вашей логики вот то, что быстрый сеанс GDB находит с вашим минимальным кодом (ятолько изменил тип i в строке 75 на unsigned int):

В точке segfault:

(gdb) bt
#0  0x0000000000401112 in evaluateNeighbourNum (original=0x6034b0)
    at cells.c:153
#1  0x0000000000401350 in evaluateNeighbourNum (original=0x612f20)
    at cells.c:201
#2  0x0000000000401509 in calculate () at cells.c:229
#3  0x00000000004016c8 in main () at cells.c:250

(gdb) p *original
$14 = {
  index = 2, 
  x = 1, 
  y = 0, 
  N = 0x411, 
  S = 0x6e20666f206d754e, 
  E = 0x72756f6268676965, 
  W = 0x2029302c31282073, 
  count = 925966394, 
  used = 48
}

Как видите, N заполняетсяс мусором (0x411 не является допустимым указателем).Посмотрите, как вы заполняете свои узлы.

...