Question

I am using a vector/iterator to execute a method in different classes, this works just fine in debug and in other places where we have used the same approach. However for some reason when i run this code in release i get the following error:

Unhandled exception at 0x011d2928 in FOO.exe: 0xC0000005: Access violation.

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;
   }
}

Why do this happen? Is the error related to using the vector/iterator? What got me thinking that it has to do with the iterator is that when i debug it(release) visual studio completly skip the line where i declare my iterator(this does not happen in debug).

When i debug the release build i get the error when trying to execute the line:

result = (*it)->DoSomething(s1, s2);
Was it helpful?

Solution

You cannot keep a pointer of a temporary object. The memory will be reused, so you have invalid memory access

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.

As you need polymorphism, you should do that instead, smart pointer must be prefered over naked pointer.

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

OTHER TIPS

You are adding addressed of a temporary objects with

vectorClasses.push_back(&SomeClass1());

the issue is that the object is not valid after the statement.

Instead of this:

vectorClasses.push_back(&SomeClass1());

You need this:

vectorClasses.push_back(new SomeClass1());

In the first (wrong) case, you are storing the address of a temporary object which will soon be destroyed and therefore unusable. In the second (fixed) case, we are storing a heap-allocated object which will live until you delete it (which you ought to do at the end of your program, but if you forget the operating system will clean up the allocated memory).

Following should fix your issue, it doesn't keep any more reference to deleted temporary:

SomeClass1 someClass1;
SomeClass2 someClass2;
SomeClass3 someClass3;

std::vector<AbstractClass*> vectorClasses;
vectorClasses.push_back(&someClass1);
vectorClasses.push_back(&someClass2);
vectorClasses.push_back(&someClass3);

assuming you don't delete vectorClasses content.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top