EDIT: What I thought was a bug-correction was nothing but a random fix. I was forgetting to free up heap memory correctly. See the actual code and explanation at the bottom (I'm not sure if I should have edited the whole question).
I haved fixed a bug, but do not understand what it's causing it.
If I use a helper pointer to access the element of a list in the heap, and modify its contents, everything's fine. However, if I directly modify the contents of the element using a function that returns that pointer, then this data gets corrupted at a later stage when allocating more memory.
The error only appears when the code is run in a loop, on the 6th cycle.
Code does not work
// numEvents gets corrupted after some cycles
lstEvent_NewList(&lstEvent, 1, &err); // creates a list of typeEvent in heap
//...
lstEvent_FirstNode(&lstEvent)->numEvents = events; // access first element of list directly
//...
typeCommand * p = 0;
p = (typeCommand *) malloc(sizeof(typeCommand)); // do some more allocations
lstField_NewList(&p->lstFields, 5, &err); // THIS LINE CAUSES CORRUPTION IN numEvents
Code does work
typeEvent * pEvent; // use an auxiliar to iterate through the list
lstEvent_NewList(&lstEvent, 1, &err);
//...
pEvent = lstEvent_FirstNode(&lstEvent);
pEvent->numEvents = events;
//...
typeCommand * p = 0;
p = (typeCommand *) malloc(sizeof(typeCommand)); // do some more allocations
lstField_NewList(&p->lstFields, 5, &err); // all is good
So, basically if I use an auxiliar to get the first element of the list nothing happens. However, if I use the function to directly access the first element, it breaks later on in the program.
Structure and function definitions:
typeEvent * lstEvent_FirstNode (LSTEvent *lst)
{
return lst->ls;
}
void lstEvent_NewList (LSTEvent * lst, uint16_t size, uint8_t * err)
{
typeEvent* ret = 0;
ret = (typeEvent*)malloc(sizeof(typeEvent)*size);
if (ret == 0)
{
*err = E_RUN_OUT_OF_MEM;
lst->cn = 0;
return;
}
*err = 0;
lst->ls = ret;
lst->cn = size;
}
void lstField_NewList (LSTField * lst, uint16_t size, uint8_t * err)
{
typeField* ret = 0;
ret = (typeField*)malloc(sizeof(typeField)*size);
if (ret == 0)
{
*err = E_RUN_OUT_OF_MEM;
lst->cn = 0;
return;
}
*err = 0;
lst->ls = ret;
lst->cn = size;
}
void lstEvent_ClearList (LSTEvent * lst)
{
free(lst->ls);
lst->ls = 0;
lst->cn = 0;
}
void lstField_ClearList (LSTField * lst)
{
free(lst->ls);
lst->ls = 0;
lst->cn = 0;
}
struct DM_Field{
__packed uint8_t value;
};
typedef struct DM_Field typeField;
typedef struct LSTField {
__packed uint16_t cn; // Count, number of elements in array
uint8_t * ls; // Array
} LSTField;
struct DM_Command{
// some data
LSTField lstFields;
};
typedef struct DM_Command typeCommand;
Platform: STM32L1XX.
EDIT: This code resembles closer the reality.
Code does not work
typeCommand * p = 0;
for (uint16_t i=0; i<1000; i++)
{
// numEvents gets corrupted after some cycles
lstEvent_NewList(&lstEvent, 1, &err); // creates a list of typeEvent in heap
//...
lstEvent_FirstNode(&lstEvent)->numEvents = events; // access first element of list directly
//...
p = (typeCommand *) malloc(sizeof(typeCommand)); // do some more allocations
lstField_NewList(&p->lstFields, 5, &err); // THIS LINE (was thought to be causing) CORRUPTION IN numEvents
//...
lstEvent_ClearList(&lstEvent);
lstField_ClearList(&p->lstFields);
p = 0;
}
Code does work
typeCommand * p = 0;
typeEvent * pEvent; // use an auxiliar to iterate through the list
for (uint16_t i=0; i<1000; i++)
{
lstEvent_NewList(&lstEvent, 1, &err);
//...
pEvent = lstEvent_FirstNode(&lstEvent);
pEvent->numEvents = events;
//...
p = (typeCommand *) malloc(sizeof(typeCommand)); // do some more allocations
lstField_NewList(&p->lstFields, 5, &err); // all is good
//...
lstEvent_ClearList(&lstEvent);
lstField_ClearList(&p->lstFields);
free(p); // freeing properly now
p = 0;
}