#c #pointers #vector #parameter-passing #visibility
#c #указатели #вектор #передача параметров #видимость
Вопрос:
Не мог бы кто-нибудь, пожалуйста, взглянуть на следующие фрагменты кода (все из одного файла) и посоветовать проблему, которую я опишу в конце?
Участники:
std::vector<cHasAMyClass> collected;
std::vector<cHasACHasAMyClass> memberVector;//Actually an array of vectors, but simpler not to be.
конструктор внутреннего / локального класса:
cHasACHasAMyClass(cHasAMyClass *ptrToCHasAMyC, int stuff) :
masterRef(ptrToCHasAMyC),
other_stuff(stuff) {}
метод, который я использовал:
cHasAMyClass *firstUniqueOccurrence(std::vector<cHasAMyClass> *masterList, myClass *qSq) {
for (int i = 0; i < (int)masterList->size(); i)
if ((*masterList)[i].myClassPtr == qSq) return amp;((*masterList)[i]);
masterList->push_back(cHasAMyClass(qSq));
return amp;(masterList->back());
}
, который вызывает указанный выше метод:
{
std::vector<myClass *> allAtLoc;
if (map->getAllHere(curLoc, amp;allAtLoc)) {
for (int i = 0; i < (int)allAtLoc.size(); i) {
int stuff = 42; //Or otherwise
cHasAMyClass *newContainer = firstUniqueOccurrence(amp;(collected), allAtLoc[i]);
memberVector.push_back(cHasACHasAMyClass(newContainer, stuff));
}
}
allAtLoc.clear();
}
Проблема в том, что некоторое время спустя (обычно сразу после выхода из вышеуказанного блока) memberVector[0].masterRef
появляется ошибка, которую я обнаруживаю (помимо сбоя), потому что его член типа myClass
недопустим или равен нулю. Я думал, что установил для него указатель на сохраняющийся объект (управляемый в другой структуре данных, простой массив (/ ptr — это new
/ malloc
‘d)), но я новичок в использовании векторов и не уверен, какую косвенность я наблюдал.
У меня есть allAtLoc
и newContainer
выходит за рамки, и хотя они являются всего лишь указателями на объекты, у них есть побочные эффекты. Кстати, мой collected
вектор не содержит ошибок.
Все это работало нормально до того, как я перешел на std::vector
s, я не понимаю, как моя косвенность неверна, пожалуйста, может кто-нибудь посоветовать?
Комментарии:
1. можете ли вы показать рабочий код перед векторами? поможет обнаружить любые неправильные преобразования.
2. есть только код для
myClass **map->getAllHere(
сохранения в этом источнике, мне нужно будет выполнить поиск в более ранних архивах для альтернативного кода выше…
Ответ №1:
Трудно читать ваш код, но похоже, что вы берете указатели на элементы внутри a vector
. Указатели, итераторы и ссылки на a vector
становятся недействительными при изменении его емкости. Это может произойти как побочный эффект любой функции, которая вставляется в vector
, поскольку создается новый больший внутренний массив, в который копируется текущее содержимое.
Если вы хотите использовать указатели на элементы в a vector
, вы должны убедиться, что они не будут признаны недействительными. Если вы знаете количество элементов, вы можете вызвать reserve
его перед вставкой любых элементов.
Комментарии:
1. Элементы сохраняются с использованием стандартного указателя на
new
общую выделенную память, как только что добавлено в моем обновлении. Ах, теперь я понимаю, что вы имеете в виду, вызовmasterList->push_back
аннулирует любые ссылки, которые я, возможно, ранее сделал для него!vector
в конце концов, это не такая уж экономия труда! Я наблюдал в основном повреждение первых элементов, что немного странно, поскольку я ожидал, что память останется непрерывной. Однако мне нужно было бы лучше проверить наличие более тонких повреждений.2. @John: Именно потому, что память остается непрерывной, указатели становятся недействительными.
3. да, но разве это не приведет к аннулированию всех смежных элементов, я нашел {bad line= 0, ok line= 1,2,4,5,6 ok bad line = 3}, но я не проверял все это тщательно. Поскольку я не знаю размер, вы предлагаете мне вернуться к
new
указателям и?4. @John: Когда указатели, ссылки и итераторы признаются недействительными, это документируется и гарантируется стандартом. Проведите некоторое исследование по этому вопросу. Если используется
vector
для замены массива в стиле C, просто вызовитеreserve(size)
его после его инициализации.