3

I am currently working on a project that requires some allocation and deallocation of large arrays on a PIC32MX775. I have a dedicated heap memory size of 1500 bytes, which should be more than sufficient and I have previously had the system allocating and deallocating memory correctly when using standard float types. However, I have recently introduced a new variable type:

typedef struct{
char index;
float gain;
float freq;   }RM_EQ_SORT_ELEMENT;

With this replacing three separate arrays I have had problems deallocating the memory using the 'free()' function ever since. An example of the arrays and how I'm trying to free them is below:

float* freq = (float*)malloc(NO_OF_FREQS*sizeof(float)); // For the unsorted average frequency
RM_EQ_SORT_ELEMENT* sortArray = (RM_EQ_SORT_ELEMENT*)malloc(NO_OF_FREQS*sizeof(RM_EQ_SORT_ELEMENT));

//**Some more code here that uses the arrays**

if(freq != NULL){
   free(freq);
}

if(sortArray != NULL){
   free(sortArray);
}

Whilst debugging, the code will jump into the 'excep_bp' loop found at the bottom of the included exceptions.c file, when the PIC32 hits either of the above free statements. If their order is changed the same result occurs.

Are there any common problems that might occur when deallocating memory like this with a PIC32? Also I understand that I might be able to debug this problem more thoroughly, any advice on what to do in this situation would help.

Michael Karas
  • 56,889
  • 3
  • 70
  • 138
  • Which compiler, and which version of that compiler, are you using? – Majenko Jun 09 '15 at 10:21
  • I have been using the new XC32 v1.34, for a few weeks now. – Thomas Grainge Jun 09 '15 at 10:25
  • 1
    Are you absolutely positive that you are receiving valid memory from malloc? Casting the return value of malloc is a bad idea, as it should return void*, which will automatically promote. Casting it can hide errors during the call. Edit: That of course, if for C. For C++, you should be using new. – R Drast Jun 09 '15 at 10:30
  • I am able to use the arrays throughout the function. There has never been an issue when accessing the memory and i have been using it without any errors. So i assume that it has been correctly allocated. I will remove the cast and get back to you. – Thomas Grainge Jun 09 '15 at 10:37
  • 3
    Then also, in the rest of the code, are you positive that you aren't doing something to the returned pointer value itself? Possibly overwriting it through a simple typo? except_bp is normally a breakpoint exception, which is odd there. – R Drast Jun 09 '15 at 10:38
  • 2
    To what value does `NO_OF_FREQS` expand to? Also, try not doing anything with `freq` and `sortArray` and see if you still get any errors when freeing. Make sure you're not doing something like `freq++` or similar. – apalopohapa Jun 09 '15 at 10:45
  • 2
    @Thomas you should always check the pointer returned by malloc against NULL. But why are you using the heap at all? If you are sure that you have the memory, why not allocate either globally or locally? – Wouter van Ooijen Jun 09 '15 at 10:57
  • @Drast I am checking for pointer interactions and movement and i haven't been overwriting it anywhere, So the pointer shouldn't be lost. I'm currently moving the `free(freq)` back though the code in order to check again for this problem. – Thomas Grainge Jun 09 '15 at 10:58
  • @apalopohapa `NO_OF_FREQS` is currently defined as 34. I will take a look at what I'm doing with the pointer in the different functions. – Thomas Grainge Jun 09 '15 at 11:01

1 Answers1

5

It is possible that when you added the new data type to your arrays of allocated data that its increased size is exposing an off-by-one error in your code. If by chance you are accessing an array by one too many elements there is a good chance that you are corrupting the header(s) that the heap manager puts in between MALLOCed blocks. When FREE comes along and depends in this header information to be correct all nature of things can go wrong when it is corrupted.

When you had the smaller item size in your arrays you may still have had the off by one error but the MALLOC headers may not have been getting corrupted in an immediately harmful way.

There are also compiler specific ways that the heap manager routines work. It is possible that in some cases the manager may allocate space in certain minimum number of byte sized blocks. It is just possible that in your simpler case that appeared to work that there was unused block space in the MALLOC area that was swallowing up your smaller sized off by one error without harm. When you come with a greater element size maybe the heap manager is not being so kind to you.

Michael Karas
  • 56,889
  • 3
  • 70
  • 138
  • 2
    +1, I think that's most you can say with the given clues and it's very educative, for me at least. – Vladimir Cravero Jun 09 '15 at 12:21
  • Any thoughts about best practices to defend against this kind of errors (well, except units test which are never a bad idea)? Would using valgrind help? – 0x6d64 Jun 09 '15 at 13:13
  • 1
    @0x6d64 Yeah.. not using dynamic memory allocation on embedded systems without an OS :-) – m.Alin Jun 09 '15 at 13:18
  • @Michael I have tried a number of methods to solve the problem and after taking all the advice on this thread it was apparent to me that my code was not at fault. This led me to change my compiler to v1.3 and then back to v1.34, which has seemingly solved the problem but, I believe the answer is in fact related to what @Drast mentioned in his comment on the original question regarding the `excep_bp` actualy being a breakpoint exception that was happening whilst the MCU was executing the `free()` function. – Thomas Grainge Jun 09 '15 at 14:21
  • I can understand that in some cases you could see failure symptoms change when switching from one compiler version to another - but I do not buy that changing version of compiler from X to Y and the back to X has fixed anything - especially of there were no changes in the source code. – Michael Karas Jun 10 '15 at 09:06
  • I think that one of the best pieces of advice so far was to perform the MALLOC_1 then MALLOC_2 then NO-CODE then FREE and FREE. You did not give any indication of the result of that test. – Michael Karas Jun 10 '15 at 09:10
  • 1
    I am not fully able to offer anything about a breakpoint exception. If I was getting that type of behavior I think the first thing I would try was to delete every breakpoint and then try running the code again. I do note that MPLABX seems to have a habit of remembering every breakpoint that was set even across multiple compiles and debug enteries. I suppose it is possible such situation led to an invalid breakpoint execution when the code changed a small bit between to debug flows. Was it possible that you had some data type breakpoints active in the data area being freed? – Michael Karas Jun 10 '15 at 09:16
  • @MichaelKaras I tried the malloc and the immediate free and this resulted in correct heap use with no exceptions. I believe that the moving breakpoints whilst trying this solved my exception issue. You are correct the change in compiler is most likely irrelevant. I am fairly inexperienced with this issue of `except_bp` which is why I thought my memory deallocation is the issue. Now that I know i will always try removing the breakpoints, before jumping to a conclusion about the issue. – Thomas Grainge Jun 10 '15 at 09:39