0

I'm working on a project involving a PIC32MX220f032b in which i have to use dynamic memory allocation to declare an unknown number of structs in a linked list.

The malloc calls and everything worked fine, until i went on implementing the removal of the data. The idea is to allocate a number of structs and fill them with data (some via pointers). At a point in time, all known structs are freed an new ones are declared.

The first test with only allocation worked for about three rounds until it ran out of memory (understandable). But when i implement a function to free the data structures, malloc is no longer functioning. It's function call crashes the pic and sends it to its exception handler with a pointer error. But i cannot figure out why...

I use the following struct:

typedef struct image_element
{
    unsigned char conditional;
    unsigned char datafield;
    unsigned char comparisonType;
    unsigned char compareValue;
unsigned char *filename;
unsigned char active;

unsigned short xSize;
unsigned short ySize;
unsigned short xStart;
unsigned short yStart;

struct image_element *next;
}screen_image_element;

In the code, i allocate the struct and it's filename pointer with malloc:

screen_image_element *tempElement; 
tempElement = (screen_image_element *) malloc(sizeof(screen_image_element));

char *tmp;
tmp = (char *) malloc(somevalue); //somevalue is known
// fill tmp with a string
(*tempElement).filename = tmp;

After everything is allocated and used (note: this functionality all works like a charm) i want to free all data fields and start over:

void deleteMenu()
{

    screen_image_element *temp;

    while (image_elements) //image elements is the first struct in the linked list at this point
    {
        temp = image_elements->next; //save the next pointer
        free(image_elements->filename); // free the data behind the filename pointer
        free(image_elements); //free the rest of the struct
        image_elements = temp; // put the next struct as first and loop
    }
}

I cannot test the functionality of this as free doesn't provide any return values as far as i know and a cannot see the current memory usage. Until this point the pic still runs. But when i try to allocate memory again the pic crashes (exception handler called with cause 0x07: bad pointer). The problem seems to originate from inside the malloc function call as:

malloc(18);

doesn't work as well (so no fault in function parameters or something).

Do you have any idea what could be the cause of this?

dandan78
  • 13,328
  • 13
  • 64
  • 78
tim kers
  • 1
  • 3
  • 3
    Please [see why not to cast](http://stackoverflow.com/q/605845/2173917) the return value of `malloc()` and family in `C`. – Sourav Ghosh Jul 07 '15 at 13:42
  • Just saying: `note: this functionality all works like a charm`...could be UB, too. :-) – Sourav Ghosh Jul 07 '15 at 13:45
  • Add proper error-handling! – too honest for this site Jul 07 '15 at 13:47
  • Can you tell us, what kind of operations you performed with `filename`? Also, `image_elements` appears only in deletion function..... – Sourav Ghosh Jul 07 '15 at 13:48
  • Ok i will remove the casts in these calls. I didn't know that. unfortunately a lot of tutorials and examples do cast these pointers, so i assumed this was normal. The functionality "works" as all data is accounted for and am able to use all data in the structs as supposed to. So is seems to me this is ok. When i keep using the first set of data structs, i can access and use all data without any problem – tim kers Jul 07 '15 at 13:49
  • What kind of error handling do you mean Olaf? if you mean catching failed mallocs etc, this is to come. But normally if malloc just fails it'll result in a null pointer, not a crashed pic. filename points to a char array in which a string (with a file name is stored). this is copied from another buffer with strncat. This filename is used to open a file on a sdcard (with fatfs) to process some data in it. image_elements is a pointer to the first struct in the linked list. At the end of the second code part i put the pointer of tempElement in image_elements (if it is the first one) – tim kers Jul 07 '15 at 13:54
  • What OS is this and why do you have to use dynamic memory allocation? Who are you sharing the RAM with? If you have no OS and therefore aren't sharing the memory with anyone, [dynamic allocation makes no sense!](http://electronics.stackexchange.com/questions/171257/realloc-wasting-lots-of-space-in-my-mcu/171581#171581). – Lundin Jul 07 '15 at 13:55
  • There is no OS. It is on a PIC32 microcontroller. I use dynamic memory allocation because it loads an unknown amount of data structs of different size (in the future) from a SD card. The amount of data is only known at runtime when the system is reading the card. – tim kers Jul 07 '15 at 13:58
  • 1
    @timkers That makes no sense on an embedded system, you don't have "an unknown amount of RAM" on your chip. Read the link I posted. So what you can do is to go to your linker file, see how much memory the heap uses, _remove the heap altogether and replace it with a plain static array_. Your program will become much faster and consume _exactly the same amount of memory_. – Lundin Jul 07 '15 at 14:01
  • I understand the 'problems' with dynamic allocation. But i don't know beforehand what amount of memory i need. eventually 4 types of structs will be defined (different sizes) and depending on the data on the sd card a number of each will be needed at different times. If i allocate this static, wouldn't i just limit my possibilities a lot? For example. say all structs are the same size, and i have space for 100 structs in ram. When i give all types a static array of 25 i fail when i only have 40 structs of 1 type although i would have the ram. Or is there another way to do something like this? – tim kers Jul 07 '15 at 14:09
  • You could not know how much memory will your application need, but do you know how much memory your PIC32 has. Than, as @Lundin suggested you, you can profile your memory with the max handable structures you can affort. – LPs Jul 07 '15 at 14:13
  • What compiler are you using? – chux - Reinstate Monica Jul 07 '15 at 14:14
  • I am using the microchip XC32 compiler (pro version). I can indeed allocate all available memory with data structs. But is there a technique i don't know to cope with different sizes of structs? Or just divide the available ram in chucks and live with it? Another option would be to change the data structs to a general type usable for all 4 versions. But this would eat a lot more memory per struct – tim kers Jul 07 '15 at 14:20
  • @timkers Sorry but you _must_ know the amount of memory in advance. Otherwise how can you pick the appropriate MCU for the task? Or what did you intend to do when you run out of memory, crash & burn? Data types is just a way to label a chunk of memory. – Lundin Jul 07 '15 at 14:21
  • Ideas: 1) help compiler with data packing: re-order to pointers, shorts, chars. 2) after allocating (and checking it is not NULL), zero fill structure 3) `tmp = malloc(somevalue); (*tempElement).filename = tmp;` is suspicious. Concern filename space is insufficient. Better to see that code too. – chux - Reinstate Monica Jul 07 '15 at 14:24
  • Ok, i've changed some aspect of the system en redefined the data structures. Now the struct is constant of size and type (1 general version instead of 4 different). So i will now use static allocation with a struct array of maximum size in ram. But apart from that, i still have no clue what could be causing the problem. Anyone having any idea? – tim kers Jul 09 '15 at 07:06

0 Answers0