Я использую vector/iterator для выполнения метода в разных классах, это отлично работает при отладке и в других местах, где мы использовали один и тот же подход. Однако по какой-то причине, когда я запускаю этот код в выпуске, я получаю следующую ошибку:
Необработанное исключение в 0x011d2928 в FOO.exe: 0xC0000005: нарушение прав доступа.
std::vector<AbstractClass*> vectorClasses;
vectorClasses.push_back(&SomeClass1());
vectorClasses.push_back(&SomeClass2());
vectorClasses.push_back(&SomeClass3());
CString result;
std::vector<AbstractClass*>::iterator it
for(it = vectorClasses.begin() ; it != vectorClasses.end() ; it++)
{
result = (*it)->DoSomething(s1, s2);
if(!IsBlank(result))
{
//Do something
break;
}
}
Почему это происходит? Является ли ошибка связана с использованием вектора/итератора? Что заставило меня думать, что это связано с итератором, так это то, что когда я отлаживаю его (выпуск), визуальная студия полностью пропускает строку, где я объявляю свой итератор (это не происходит при отладке).
Когда я отлаживаю сборку релиза, я получаю ошибку при попытке выполнить строку:
result = (*it)->DoSomething(s1, s2);
Вы не можете сохранить указатель на временный объект. Память будет повторно использована, поэтому у вас есть недопустимый доступ к памяти
std::vector<AbstractClass*> vectorClasses;
vectorClasses.push_back(&SomeClass1()); // ill formed, SomeClass1() is create on the stack and destroy after push_back call is done, referencing the pointer after that is invalid as it will not be a SomeClass1 anymore.
Поскольку вам нужен полиморфизм, вы должны это сделать, а умный указатель должен быть предпочтен по голой стрелке.
std::vector<std::unique_ptr<AbstractClass>> vectorClasses;
vectorClasses.push_back( std::make_unique<SomeClass1>() );
vectorClasses.push_back( std::make_unique<SomeClass2>() );
vectorClasses.push_back( std::unique_ptr<SomeClass3>( new SomeClass3{} ) ); // if make_unique not available
Вы добавляете обращение к временным объектам с
vectorClasses.push_back(&SomeClass1());
проблема в том, что объект недействителен после инструкции.
Вместо этого:
vectorClasses.push_back(&SomeClass1());
Ты нуждаешься в этом:
vectorClasses.push_back(new SomeClass1());
В первом (неправильном) случае вы храните адрес временного объекта, который вскоре будет уничтожен и, следовательно, не будет использоваться. Во втором (фиксированном) случае мы храним объект, выделенный для кучи, который будет жить до тех пор, пока вы его не delete
(что вы должны делать в конце вашей программы, но если вы забудете, что операционная система очистит выделенную память),
Следующее должно исправить вашу проблему, оно больше не содержит ссылки на удаленные временные:
SomeClass1 someClass1;
SomeClass2 someClass2;
SomeClass3 someClass3;
std::vector<AbstractClass*> vectorClasses;
vectorClasses.push_back(&someClass1);
vectorClasses.push_back(&someClass2);
vectorClasses.push_back(&someClass3);
если вы не удаляете содержимое vectorClasses
.
s2
? что происходит в конструктореSomeClass1
? покажи нам код.vectorClasses.push_back(&SomeClass1());
добавить адрес временного ...