Обновление значения переменной в структуре приводит к изменению другой переменной из той же структуры - PullRequest
0 голосов
/ 07 мая 2019

Я работаю над кодом, который обрабатывает трафик в перекрестках с течением времени и возвращает количество трафика, находящегося в перекрестке в данный момент времени.

В принципе, у меня проблема с массивом структур, гдекаждая структура содержит 2 вектора: один с координатами пересечения (x, y), а другой отслеживает, сколько автомобилей прошло в момент t на это пересечение (каждый слот от 0 до n представляет время, значение внутри - это количество автомобилейкоторый пересекся в то время).

Вот структура:

typedef struct intersection {
  int coords[2];
  int timeslots[];
} intersection;

, которая содержится в массиве пересечений из этой структуры:

typedef struct simulation {
  int h_streets; //row (horizontal streets)
  int v_streets; //column (vertical streets)
  int n_cars;    //cars number
  int n_trips;   //trips number

  car car_pos [1000];

  intersection intersections [];
} simulation;

Затем память выделяетсяmalloc для определения фактического размера массива для гибких массивов при считывании необходимых данных:

  struct simulation * this = malloc( sizeof(simulation) + (sizeof(intersection)*(h_streets*v_streets)*(sizeof(int)*(max_time+1001))) );

При чтении данных, касающихся поездки автомобиля из одной позиции в другую, я делаю, как было сказано выше, увеличение временных интервалов [t] на единицу, когда машина пересекает этот перекресток в то время.

Проблема в том, что, когда я делаю это с этой линиейКод, содержащийся во временном цикле

this->intersections[curr_int].timeslots[starting_t+travel_t]++;

значение из массива координат изменено.

Вот пример при печати только координат пересечений в каждом цикле:

------------------
i: 0, h: 0, v: 0
i: 1, h: 0, v: 1
i: 2, h: 0, v: 2
i: 3, h: 0, v: 3
i: 4, h: 1, v: 0
i: 5, h: 1, v: 1
i: 6, h: 1, v: 2
i: 7, h: 1, v: 3
i: 8, h: 2, v: 0
i: 9, h: 2, v: 1
i: 10, h: 2, v: 2
i: 11, h: 2, v: 3
i: 12, h: 3, v: 0
i: 13, h: 3, v: 1
i: 14, h: 3, v: 2
i: 15, h: 3, v: 3
------------------
------------------
i: 0, h: 0, v: 0
i: 1, h: 1, v: 1
i: 2, h: 0, v: 2
i: 3, h: 0, v: 3
i: 4, h: 1, v: 0
i: 5, h: 1, v: 1
i: 6, h: 1, v: 2
i: 7, h: 1, v: 3
i: 8, h: 2, v: 0
i: 9, h: 2, v: 1
i: 10, h: 2, v: 2
i: 11, h: 2, v: 3
i: 12, h: 3, v: 0
i: 13, h: 3, v: 1
i: 14, h: 3, v: 2
i: 15, h: 3, v: 3
------------------
------------------
i: 0, h: 0, v: 0
i: 1, h: 1, v: 2
i: 2, h: 0, v: 2
i: 3, h: 0, v: 3
i: 4, h: 1, v: 0
i: 5, h: 1, v: 1
i: 6, h: 1, v: 2
i: 7, h: 1, v: 3
i: 8, h: 2, v: 0
i: 9, h: 2, v: 1
i: 10, h: 2, v: 2
i: 11, h: 2, v: 3
i: 12, h: 3, v: 0
i: 13, h: 3, v: 1
i: 14, h: 3, v: 2
i: 15, h: 3, v: 3
------------------
------------------
i: 0, h: 0, v: 0
i: 1, h: 1, v: 2
i: 2, h: 0, v: 2
i: 3, h: 0, v: 3
i: 4, h: 2, v: 0
i: 5, h: 1, v: 1
i: 6, h: 1, v: 2
i: 7, h: 1, v: 3
i: 8, h: 2, v: 0
i: 9, h: 2, v: 1
i: 10, h: 2, v: 2
i: 11, h: 2, v: 3
i: 12, h: 3, v: 0
i: 13, h: 3, v: 1
i: 14, h: 3, v: 2
i: 15, h: 3, v: 3
------------------
[...]

(i - счетчик цикла, который обращается к перекресткам [] в позиции i, тогда как h и v - горизонтальные и вертикальные координаты пересечения i, содержащиеся в массиве ords [])

Как выМожно заметить, что координаты некоторых пересечений изменяются после каждого цикла, хотя я даже не обращаюсь к этому массиву с помощью функции увеличения

this->intersections[curr_int].timeslots[starting_t+travel_t]++;

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

1 Ответ

2 голосов
/ 07 мая 2019

В этом коде, который объявляет член simulation:

intersection intersections [];

intersections - это структура с элементом гибкого массива, поэтому приведенный выше код пытается создать массив структур с элементом гибкого массива.

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

Этот код пытается использовать массив структур с гибкими элементами массива:

this-> Пересечения [curr_int] .timeslots [starting_t + travel_t] ++;

В этом коде компилятор не может знать, сколько элементов имеет массив this->intersections[curr_int].timeslots. Поскольку timeslots является гибким элементом массива, каждый экземпляр intersection может иметь различное количество элементов в его timeslots - цель состоит в том, чтобы программист предоставил любой объем пространства, требуемый для каждого экземпляра. Поскольку это количество может варьироваться в зависимости от каждого экземпляра, они не могут быть организованы в массив элементов фиксированного размера, и компилятор не может знать, насколько велик каждый из них.

Поскольку компилятор не знает, сколько элементов должен иметь программист в каждом timeslots, он не знает, насколько велик каждый intersection. При вычислении адреса для this->intersections[curr_int] компилятор использует только размер структуры, как если бы он был определен без элемента гибкого массива (за исключением вопроса заполнения). Это вычисление не будет правильным, когда программист намеревается присутствовать члены гибкого массива.

И Clang, и GCC предупреждают об этом, когда используется переключатель -pedantic.

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

...