Я объявил такую структуру и следующие структуры данных
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];
}
Что ж, до сих пор у меня не было проблем. Однако позже в программе я должен использовать часть piece *, для этого я использую итератор, подобный этому
for(map< int, piecesTog* >::iterator it = data.begin(); it != data.end(); it++){
piece* aux = it->second;
...
}
Я хочу получить доступ к структуре, на которую указывает it-> second, но я все перепробовал, и ничего не сработало.
Я напечатал адрес памяти it-> second и &iecesTog [tam], и они такие же, но когда я напечатал (* aux) .height или it-> second-> height, они выдают число совершенно сумасшедшее, возможно, какой-то мусор.
Я понятия не имею, почему это происходит.
Если у кого-то есть идеи, как это исправить, я был бы признателен.
Так как это помечено C++, почему вы все равно используете scanf
? Есть варианты получше типа while(std::cin >> aux1 >> aux2 >> aux3)
Вы не можете этого сделать, потому что это действительно класс, и этот итератор не несет с собой никаких объектов. Вместо этого вы можете попробовать auto iterr = data.begin()
с некоторыми (небольшими) шансами.
while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF){
piecesTog.push_back( piece(aux1, aux2, aux3) );
data[a] = data[c] = &piecesTog[tam];
}
почти наверняка не следует Правила аннулирования итератора.
piecesTog.push_back( piece(aux1, aux2, aux3) );
может инициировать изменение размера, которое обычно создает новое хранилище данных, копирует элементы из старого хранилища данных в новое, а затем удаляет старое хранилище данных, оставляя указатели кешированными
data[a] = data[c] = &piecesTog[tam];
болтается. Когда вы когда-нибудь в будущем воспользуетесь этими указателями, Ka-Blammo! Неопределенное поведение и легко идентифицированный сбой, если вам повезет.
Для окончательного решения предоставлено недостаточно информации, но вот несколько общих альтернатив (в порядке привлекательности):
Если вы заранее знаете количество piece
, которые войдут в piecesTog
, вы можете использовать хранилище reserve
, чтобы избавиться от необходимости изменять размер vector
.
Если элементы добавляются только в конец vector
и никакие элементы никогда не удаляются, вы можете хранить индексы элементов, а не указатели на них. Если порядок никогда не меняется, индексы всегда будут ссылаться на правильные элементы, независимо от того, сколько еще элементов добавлено.
Если это возможно, перепишите считывающее устройство, чтобы загрузить все pieces
в piecesTog
, а затем постройте карты.
Все вышеперечисленные варианты предполагают, что piecesTog
собирается сразу, а затем остается в покое. Если ваша вставка имеет более произвольную форму, вы сортируете структуру или удаляете элементы, вам нужно будет использовать структуру данных с более благоприятными правилами аннулирования, такими как std::list
.
while(scanf("%d %d %d", &aux1, &aux2, &aux3) != EOF)
полностью игнорирует все, что может пойти не так, кроме EOF, что может привести к бесконечному циклу чтения мусора. Вы хотите, чтобы определенныйscanf
каждый раз считывал 3 значения, а когда этого не произошло, тогда вы хотите проверить EOF