TArray.Remove(TArray[i]) Causes a Crash

I have a TArray and another int32 value. If my other integer value is in my TArray, I want to remove it.

However, the line MyArray.Remove(MyArray[i]) causes a crash (and unfortunately a nondescript error log.)

for (int32 i = 0; i < MyArray.Num(); i++)
{
	if (MyArray[i] == OtherIntegerValue)
	{
		//MyArray.Remove(MyArray[i]); Commented out in case, somehow, MyArray doe not contain this?
		if (MyArray.Contains(MyArray[i]))
		{
			UE_LOG(LogTemp, Log, TEXT("We have it!"));
			MyArray.Remove(MyArray[i]);
		}
		else
		{
			UE_LOG(LogTemp, Log, TEXT("We oddly enough do NOT have it..."));
		}
	}
}

I know that the array contains this element, as if I comment out the Remove line, I still print out “We have it!” to the log. However, the lines int32 ThisValue = MyArray[i]; MyArray.Remove(ThisValue) works. I was curious why this is?

Hi,

TArray::Remove removes all instances of an element. So if your array contained { 1, 2, 1, 2 }, and you removed ‘1’, you’d be left with { 2, 2 }.

TArray::Remove’s argument is taken by reference, so if your reference is to an element within the container being removed from, you’d get { 2, 1 }, because it’ll remove the first element (which compares equal with itself), then assign the following 2 over it, then continue to remove 2s because that’s now the element you’re looking for.

You can use RemoveSingle, which only removes the first element it finds (and thus is not susceptible to this problem). Or you should probably call RemoveAt(i) instead, which removes the element at a given index, which you have.

However, given the code you’re written, it would be more succinct to replace it all with:

int32 NumRemoved = MyArray.Remove(OtherIntegerValue);
UE_CLOG(NumRemoved > 0, LogTemp, Log, TEXT("We oddly enough do NOT have it..."));

Hope this helps,

Steve

I ended up going with that final suggestion, thanks.

Also, I’ve never seen UE_CLOG and can’t find documentation. It looks pretty useful; do you use it the same as UE_LOG but just put in a condition first?

Cool, thanks!

Yep, that’s right. Not sure why UE_CLOG isn’t documented, but it’s been in UE4 since the first release.

Steve