3
\$\begingroup\$

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.

\$\endgroup\$
9
  • \$\begingroup\$ Which compiler, and which version of that compiler, are you using? \$\endgroup\$ Commented Jun 9, 2015 at 10:21
  • 1
    \$\begingroup\$ 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. \$\endgroup\$ Commented Jun 9, 2015 at 10:30
  • 3
    \$\begingroup\$ 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. \$\endgroup\$ Commented Jun 9, 2015 at 10:38
  • 2
    \$\begingroup\$ 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. \$\endgroup\$ Commented Jun 9, 2015 at 10:45
  • 2
    \$\begingroup\$ @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? \$\endgroup\$ Commented Jun 9, 2015 at 10:57

1 Answer 1

5
\$\begingroup\$

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.

\$\endgroup\$
8
  • 2
    \$\begingroup\$ +1, I think that's most you can say with the given clues and it's very educative, for me at least. \$\endgroup\$ Commented Jun 9, 2015 at 12:21
  • \$\begingroup\$ 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? \$\endgroup\$ Commented Jun 9, 2015 at 13:13
  • 1
    \$\begingroup\$ @0x6d64 Yeah.. not using dynamic memory allocation on embedded systems without an OS :-) \$\endgroup\$ Commented Jun 9, 2015 at 13:18
  • \$\begingroup\$ @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. \$\endgroup\$ Commented Jun 9, 2015 at 14:21
  • 1
    \$\begingroup\$ 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? \$\endgroup\$ Commented Jun 10, 2015 at 9:16

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.