C++ Vector Access Violation Run-Time Crash

I’m currently creating a stealth/detection system that uses a vector (the std C++ list, not points in 3D space) belonging the the NPC’s AI to keep track of how close an NPC is to detecting another pawn. ~ Every .25 seconds, a “detect” function is called to tick all relevant entries in the DetectionVector. I’ve been testing it with one NPC detecting only the player, and it runs flawlessly until approx. 1 min of run-time where I get the crash report:

MachineId:1629E91E4FEAC8CEF7551A90ACAA1D98
EpicAccountId:6339694411d143cbb8e2755eb87c3e48

Access violation - code c0000005 (first/second chance not available)

    UE4Editor_CoreUObject + 1450875 bytes
    UE4Editor_Engine + 6316830 bytes
    UE4Editor_Engine + 6417331 bytes
    UE4Editor_Engine + 5343028 bytes
    UE4Editor_Engine + 3542178 bytes
    UE4Editor_Engine + 9302478 bytes
    UE4Editor_UnrealEd + 1806471 bytes
    UE4Editor_UnrealEd + 6686342 bytes
    UE4Editor!FEngineLoop::Tick() + 3876 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.6\engine\source\runtime\launch\private\launchengineloop.cpp:2214]
    UE4Editor!GuardedMain() + 479 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.6\engine\source\runtime\launch\private\launch.cpp:131]
    UE4Editor!GuardedMainWrapper() + 26 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.6\engine\source\runtime\launch\private\windows\launchwindows.cpp:126]
    UE4Editor!WinMain() + 249 bytes [d:\buildfarm\buildmachine_++depot+ue4-releases+4.6\engine\source\runtime\launch\private\windows\launchwindows.cpp:202]
    UE4Editor!__tmainCRTStartup() + 329 bytes [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c:618]

The relevant part of the function is here:

index = FindDetectionInfo(target); //Find our target DetectionInfo

if (index != -1) //If an info was found, store it
{
	DetInfo = DetectionVector.at(index);
}
else //Otherwise, make a new one and store that
{
	DetectionVector.push_back(new UDetectionInfo(target, 0.0));
	DetInfo = DetectionVector.back();
}

And the FindDetectionInfo function:

int32 AnpcAI::FindDetectionInfo(APawn* target)
{
	bool foundInfo = false;
	int foundIndex = -1;
	for (int i = 0; i < DetectionVector.size() && !foundInfo; i++) //Iterate through the vector until we find our Info
	{
		if (DetectionVector.at(i)->getTarget() == target)
		{
			foundInfo = true;
			foundIndex = i;
		}
	}
	return foundIndex;
}

I have already debugged this, ensuring that only one entry in the vector is created, that it updates properly, etc. I have also determined that these lines are what cause the crash. At this point, I believe that there may be a UE4 flaw rather than a scripting error, so any help/advise would be appreciated!

Other info:
Running on UE 4.6
Using Windows 7 x64

Vector is declared as: std::vector DetectionVector;

All unreal object pointers can become NULL. Eventhough they look as ‘naked’ pointers, they are managed.

The line:
" if (DetectionVector.at(i)->getTarget() == target) "
should check for if DetectionVector.at(i) != NULL.

Furthermore, as suggested use TArray instead of std::vector. This might be the reason Unreal things the object is not longer referenced and therefore collected by the gc.Hence it becomes an invalid pointer in your std::vector.

You should use TArray<> instead of std::vector<>. The std:: container classes do not play well with the way UE handles memory allocation, copying, moving, etc. Even if the problem is somewhere else in the code, the first suggestion you will receive when working with UE4 will be to use its own container types, not the stuff from the STL.

Edit:

I would also like to point out that since you’re putting UObjects inside of a container, you will need to declare the member property which is the container as a UPROPERTY(), otherwise the GC system will not be able to find any references to the UObjects, and they will be garbage collected, result in invalid pointers. You cannot declare a std::vector as a UPROPERTY, so you will need to use TArray, as I mentioned earlier.

Is UDetectionInfo derived from UObject? If so you should be using NewObject() or ConstructObject() instead of new UDetectionInfo to create new instances of that type.

Thanks for pointing that out. I’ve looked into those functions, but how exactly can I pass arguments to the UObject-derived class’ constructor through them?

Thanks for the advice. I understand why the pointer to an element of the vector (now TArray) would become dangling, but why would a pointer that is an element of the TArray suddenly dangle? I’m having them point to addresses on the heap, so I don’t understand why they would disappear, but if they do so, how can I retrieve their new location?

You can’t, at least not at the moment. You need to construct the object first using NewObject() or ConstructObject() and then set the relevant members to their default value. This is a bit tedious, so you should consider whether your class really needs to be derived from UObject, the docs provide a list of benefits that are provided by UObject to help you choose if it’s worth it or not.

If you simply need something to hold some data consider using a struct instead, these can be easily exposed to UnrealEd and replication by marking them with USTRUCT, and can be created just like regular C++ structs (so you can implement any constructor you want).

Last thing to be aware of is that classes derived from AActor should be constructed using UWorld::SpawnActor(), though it’s also possible to use deferred construction to set default values and such before spawning is finished (see UWorld::SpawnActorDeferred()).