C ++: указатель структуры в структуре карты - PullRequest
0 голосов
/ 27 октября 2018

Я объявил такую ​​структуру и следующие структуры данных

struct piece{
  int start, height, end;

  piece(int a, int b, int c){
    start = a;  height = b; end = c;
  }

};

vector<piece> piecesTog;
map <int,piece*> data;

Затем, когда я читаю элементы, я делаю это:

while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF){
    piecesTog.push_back( piece(aux1, aux2, aux3) );
    data[a] = data[c] = &piecesTog[tam];
}

Ну, до сих пор у меня не было проблем. Тем не менее, позже в программе я должен использовать кусок * part, для этого я использую итератор, подобный этому

 for(map< int, piecesTog* >::iterator it = data.begin(); it != data.end(); it++){
    piece* aux = it->second;
    ...
 }

Я хочу иметь доступ к структуре, на которую указывает it-> second, но я все перепробовал, и ничего не получалось.

Я напечатал адрес памяти it-> second и &ieceTog [tam], и они совпадают, но когда я делаю (* aux) .height или it-> second-> height, они дают число совершенно сумасшедшее, возможно, какое-то мусор.

Понятия не имею, почему это происходит.

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

1 Ответ

0 голосов
/ 27 октября 2018
while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF){
    piecesTog.push_back( piece(aux1, aux2, aux3) );
    data[a] = data[c] = &piecesTog[tam];
}

почти наверняка не следует правилам аннулирования Iterator .

piecesTog.push_back( piece(aux1, aux2, aux3) );

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

data[a] = data[c] = &piecesTog[tam];

оборванный. Когда вы будете использовать эти указатели когда-нибудь в будущем, Ка-Бламмо! Неопределенное поведение и легко определяемый сбой, если вам повезет.

Недостаточно информации для предоставления окончательного решения, но вот несколько общих альтернатив (в порядке привлекательности):

Если вы заранее знаете количество piece с, которые попадут в piecesTog, вы можете reserve хранилище, чтобы исключить необходимость изменения размера vector.

Если элементы добавляются только в конец vector и никакие элементы никогда не удаляются, вы можете хранить индексы элементов, а не указатели на них. Если порядок никогда не меняется, индексы всегда ссылаются на правильные элементы независимо от того, сколько еще элементов добавлено.

Если это возможно, перепишите программу чтения, чтобы загрузить все pieces в piecesTog, а затем постройте карты.

Все вышеперечисленные опции предполагают, что piecesTog собирается сразу, а затем остается один. Если ваша вставка более свободной формы, вы сортируете структуру или удаляете элементы, вам нужно будет использовать структуру данных с более благоприятными правилами аннулирования, такими как std::list.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...