我修复了一个错误,但不明白它导致了什么。
如果我使用帮助器指针来访问堆中列表的元素并修改其内容,那么一切都很好。但是,如果我使用返回该指针的函数直接修改元素的内容,那么在分配更多内存时,此数据会在稍后阶段被破坏。
错误仅在代码在第6个循环的循环中运行时出现。
代码不起作用
// 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
代码确实有用
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
所以,基本上如果我使用辅助来获取列表的第一个元素没有任何反应。但是,如果我使用该函数直接访问第一个元素,它会在程序中稍后中断。
结构和功能定义:
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;
平台:STM32L1XX。
编辑:这段代码更接近现实。
代码不起作用
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;
}
代码确实有用
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;
}