x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

TMap::Contains() returns false for an existing key

Hello, I am using a TMap with a custom key type and I might have found a bug.

In short:

  • I start with a TMap::Add() of three key-value pairs to the TMap, everything looks fine

  • I then TMap::Add() a fourth key-value pair

  • TMap::Contains() now returns false for the second key I added

Please note that this only happens for a few combinations of values and data types. The hash values of the 4 keys are all different.

I am attaching the two files needed to reproduce: a unit test file and the Build.cs (needed since I'm using PhysX types directly). Testing should be straightforward:

  • Create a new C++ basic code project (suggested name: FailTest. No starter content required)

  • Add the FailingTest.cpp and the FailTest.Build.cs files to the sources

  • Refresh the visual studio solution, recompile the code

  • Restart the editor and run the "Failing" unit test. An ensure() will trigger.

I've been testing this in both "DebugGame Editor" and "Development Editor" configurations for the UE 4.12.5, launcher version. As a last note, slight changes to the code (including using FVector instead of PxVec3, or removing the void* from the struct) will change behavior, which is extremely puzzling to me.

Product Version: UE 4.12
Tags:
more ▼

asked Jul 26 '16 at 01:31 PM in Bug Reports

avatar image

francesco.cat
21 2 4 8

avatar image ImVawx ♦♦ STAFF Jul 26 '16 at 08:09 PM

Hey francesco.cat,

I am not seeing the same behavior on my end. I can continue to see the second element through the ensure( ), add( ), and contains( ) function calls.

Have you tried running this outside of the unit test environment to see if you see the same result?

avatar image francesco.cat Jul 27 '16 at 09:53 AM

Hi Kyle, thanks for taking a look into this.

I managed to reproduce this behavior on 3 different PCs:

  • one is a Windows 8.1, UE 4.12.4, Visual Studio 2015 Update 2 machine

  • the other two are Windows 10, UE 4.12.5, VS 2015 Update 3 machines

I was not able to reproduce it by moving the code outside of the unreal engine's unit testing framework. Even slight modifications of the code will cause the error to just disappear. Managing to get a minimal working example was not fun!

I am now attaching the full minimal project, would you kindly give this a second shot? For me reproducing the error is as simple as:

  • open the .uproject file in UE 4.12.5, launcher version with no plugins installed, wait for the editor to finish compiling the dll

  • go to the menu "Window->Developer Tools->Session Frontend"

  • select the editor instance, go to the automation tab, select and run the FailTest

and an "Ensure condition failed" message pops up in a message log window.

Alternatively, the same error happens on my three PCs if I generate the Visual studio 2015 files, build and run the project even in "DebugGame Editor" mode.

Thank you again for your time,

Francesco

avatar image Steve Robb STAFF Jul 09 '18 at 02:22 PM

Hey,

I know this is 2 years late, but I just stumbled across this after it being linked from another issue. I'm not sure why this bug report was never assigned to me (I am the owner of TMap and the Unreal containers) - but it looks to me like the problem here is due to padding within the struct:

 struct FContactData
 {
     float Radius;
     PxVec3 Point;
     PxVec3 Normal;
     // 4 bytes of uninitialised padding inserted by compiler here!
     void const * Pointer;

     bool operator==(FContactData const & Other) const
     {
         return Radius == Other.Radius
             && Point == Other.Point
             && Normal == Other.Normal
             && Pointer == Other.Pointer;
     }

     friend uint32 GetTypeHash(const FContactData& Offset)
     {
         // This CRC hits all bytes in the struct, including the uninitialised padding
         return FCrc::MemCrc32(&Offset, sizeof(FContactData)); 
     }
 };

This is because the Pointer member needs to be at an offset which is a multiple of 8 (in a Win64 build), yet the sum of the members before is (effectively) 7 floats: 7*sizeof(float) == 28. So the compiler will insert 4 hidden bytes of padding before Pointer to ensure that it's correctly aligned.

However, this padding is left uninitialised by the compiler, and isn't being taken into account in the GetTypeHash() overload, which is just CRCing the entire memory footprint of the object, uninitialised padding included.

If you want to be able to CRC objects like this, you should manually insert the padding yourself and ensure it's always initialised to 0. A good test for this is to do:

 static_assert(sizeof(FContactData) == sizeof(float) + sizeof(PxVec3) + sizeof(PxVec3) + sizeof(void const *), "The memory footprint of FContactData is not covered by all its members");

Sorry for the delayed reply on this - hope this helps anyone else out who comes across this problem.

Steve

(comments are locked)
10|2000 characters needed characters left

1 answer: sort voted first

Hey Francesco,

Thank you for submitting a bug report with such detailed repro steps. I have reproduced this issue and logged a report for it here: https://issues.unrealengine.com/issue/UE-33818. You can track the report's status as the issue is reviewed by our development staff.

more ▼

answered Jul 27 '16 at 03:42 PM

avatar image

ImVawx ♦♦ STAFF
6.8k 114 17 127

avatar image zamy Apr 20 '18 at 01:50 PM

The bug was backlogged, but i'm randomly experiencing the same issue, outside of the test environment, and using int32 as keys.

avatar image Steve Robb STAFF Jul 09 '18 at 02:25 PM

My padding suggestion above doesn't cover your issue, so I think it is unrelated - I would suggest describing your repro steps in a new AnswerHub post, and linking to it from here.

Steve

avatar image zamy Aug 06 '18 at 01:12 PM

I'm trying to reproduce it, but after 2 hours still noting, it's pretty randomic. In my case i have 2 TMap: TMap (int32, FVector2D) and TMap (int32,int32).

The key is in common between the 2 (i mean that they always have the same amount of elements with the same keys), and add-remove are made always together. Sometimes it happens that the vector map's contains returns false even if the key is in, and the other map correctly states it has it.

(comments are locked)
10|2000 characters needed characters left
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question