question

Hao Zhou avatar image
0 Likes"
Hao Zhou asked Hao Zhou commented

std::sort() cannot sort a NodeArrayList properly

I recently noticed that std::sort() cannot sort a NodeArrayList properly if it is larger than a certain size. To replicate the problem, I create a class called SdtTester that inherits from SDT. It is a simple class that only binds three doubles. I also create a class called TestManager that inherits from FlexSimObject. A variable is created in the TestManager class to hold a bunch of SdtTesters.

In TestManager's onReset(), I create 100 StdTesters and sort them based on the third value. See the following code:

virtual double onReset() override
	{
		FlexSimObject::onReset();

		_sdtTesters.clear();
		for (int i = 0; i < 100; i++)
		{
			_sdtTesters.add(new SdtTester(uniform(-50, 50), uniform(-50, 50), uniform(-50, 50)));
		}

		std::sort(_sdtTesters.begin(), _sdtTesters.end(), [](SdtTester *lhs, SdtTester *rhs)
		{
			return lhs->getThirdVal() < rhs->getThirdVal();
		});

		return 0;
	}

This problem is FlexSim will crash by the std::sort() function. But if I change the list size to be 99 instead of 100, FlexSim will create and sort all the element properly. This is very confused.

Another problem is that if I still create 100 elements, but I sort them based on the first value instead of the third value. FlexSim will work properly.

Source code is attached for reference. samplecode.zip

Could you provide suggestions to fix it?

Thanks, Hao

FlexSim 17.1.1
nodearraylist
samplecode.zip (1.3 KiB)
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

1 Answer

Jordan Johnson avatar image
1 Like"
Jordan Johnson answered Hao Zhou commented

Usually, std::sort() works NodeListArrays. As a test to see if it is the NodeListArray or std::sort(), try putting all the object in the node list array in a vector, something like this:

std::vector<SdtTester*> testers;
testers.reserve(_sdtTesters.size());
for (SdtTester* tester : _sdtTesters) {
    testers.push_back(tester);
}
std::sort(testers.begin(), testers.end(), [](SdtTester *lhs, SdtTester *rhs) {
    return lhs->getThirdVal() < rhs->getThirdVal();
});
for (int i = 0 ; i < testers.size(); i++) {
    testers[i]->holder->rank = i + 1;
}

Let me know how that goes. If it doesn't crash, then we can look in to a bug in the NodeListArray class. If it crashes, we can look in to something else.

· 3
5 |100000

Up to 12 attachments (including images) can be used with a maximum of 23.8 MiB each and 47.7 MiB total.

Hao Zhou avatar image Hao Zhou commented ·

Hi Jordan,

Thanks for the reply. According to your suggestion, instead of calling std::sort() directly for NodeListArray, I put all objects into a vector and sort them through that vector, and it shows that sorting works properly with any size vector size. So that means NodeListArray may have problems.

0 Likes 0 ·
anthony.johnson avatar image anthony.johnson ♦♦ Hao Zhou commented ·

I bet the 100 mark is a point where std::sort switches from one sorting algorithm to another, e.g. it may do a simple insertion sort if the number of elements is less than 100, but it switches to some other algorithm when it reaches 100, and the NodeListArray doesn't work with that new algorithm. We'll have to take a look to see how that works (or, you could find the solution yourself, as the entire NodeListArray is defined in the header file for you).

1 Like 1 ·
Hao Zhou avatar image Hao Zhou anthony.johnson ♦♦ commented ·

Thank you Anthony!

0 Likes 0 ·