2

I tried to port the following C++ sorting function to C but now my embedded system goes into hard fault error while trying to sort with my new C function. The function is called roughly once every second and interestingly the first loop the sorting works, it always crashes during the second iteration.

C++ Code:

   typedef struct featureData {
        float Value[NO_OF_ATT];
        float Distance;
        bool operator < (const featureData& rhs) const {
            return Distance < rhs.Distance;
        }
    } featureData;



std::sort(trainData, trainData+NO_OF_TRAINDATA);

C Code:

int compare_function(const void *a,const void *b) 
{
featureData *x = (featureData *) a;
featureData *y = (featureData *) b;

if ( x->Distance > y->Distance ) return 1;
if ( x->Distance < y->Distance ) return -1;
return 0;
}




 qsort(trainData, NO_OF_TRAINDATA, sizeof(*trainData), compare_function);

Further information:

NO_OF_TRAINDATA = 609

NO_OF_ATT = 22

If I set the NO_OF_TRAINDATA to less than 50 the C function runs without any problems. This makes me believe that it's some memory size problem as I frequently run into memory problems on my embedded system. But does the C quicksort (Or whatever is used by calling qsort) work differently than the std::sort in terms of memory allocation?

Unfixable
  • 440
  • 1
  • 7
  • 20
  • 2
    We are no clairvoyants. "My code doesn't work" is hard to diagnose. Use a debugger. Maybe you run into stack overflow? – too honest for this site Nov 25 '15 at 09:44
  • I tested for stack overflow but I changed stack size and it's crashing at the same point so I can rule that out. I tried to catch the exception but unfortunately exception handlers are not supported on my system. What about the compare function, is it correct? The qsort parameters are also used correctly? I will try to run the same code on the desktop now to confirm whether the basic code is working – Unfixable Nov 25 '15 at 09:57
  • 2
    How is trainData declared? Submit the entire code for any healp. – mattiash Nov 25 '15 at 10:16
  • Its declared like that: featureData trainData[NO_OF_TRAINDATA]; It's filled with data from a textfile, only Distance changes each iteration, Value always stays the same. I cannot copy all as it's like 2000 lines of code overall for this class. – Unfixable Nov 25 '15 at 10:23
  • Code looks OK - problems lies elsewhere... – Paul R Nov 25 '15 at 10:26
  • How `trainData` are generated? I mean: where values are retrieved? – LPs Nov 25 '15 at 10:27
  • 1
    1. Make sure your `trainData` array is word-aligned for the processor you are using. You may need to use a #pragma to do this. 2. Make sure your `trainData` array fits in the memory (either stack or heap) that you've allocated for it. 3. If your code always crashes on the second iteration, see if your pointer to the start of `trainData` is still valid on that iteration. – sifferman Nov 25 '15 at 10:32
  • @Unfixable: One subtlety is that `qsort`/`std::sort` expects a total order for the comparison function, something which the `C`/`C++` relational operators on floats fails to provide. In particular unordered IEEE-754 NaNs may have crept in, causing an optimized sorting function to overrun the array bounds while scanning for an expected sentinel. – doynax Nov 25 '15 at 19:53
  • @doynax : Thank you for the idea, I resolved the issue now (See my answer) but I'm curious about your advice. Actually I cannot fully understand your advice and I was wondering if you have some links that explains your comment in more detail – Unfixable Nov 26 '15 at 06:12

1 Answers1

2

I found out the problem: I'm running FreeRTOS and mistakenly assumed that a task in freeRTOS is allocating it's stack memory on the system stack. What I mean is that FreeRTOS internal stack is actually allocated on the heap of my device. After increasing the device heap significantly it is running without any problems.

But I wonder about the difference between std::sort and qsort(), one was working with the smaller FreeRTOS stack while the other wasn't. I assume qsort() has a higher memory footprint which led to a stack/heap overflow.

Unfixable
  • 440
  • 1
  • 7
  • 20
  • 2
    Main problem with these functions is that [they are probably recursive](http://stackoverflow.com/questions/3379732/is-stdlibs-qsort-recursive) so they will not be kind to the stack. Just speculation, but I think perhaps that the name std::sort causes the library implementers to think outside the box and do some clever decisions about which sort algorithm to use, while the name `qsort` really does suggest Quicksort and nothing but Quicksort, even though the C standard actually does not state how that function must be implemented internally. – Lundin Nov 26 '15 at 12:37