我正在尝试将双向链表映射到GUI。我基本上为列表中的每个节点创建一个按钮结构,将节点参数映射到按钮参数,然后在屏幕上显示它们。我可以添加很多按钮,超过500个,它们似乎保持了它们独特的数据并且没有重叠。但是,当我只删除一个按钮时,下一个malloc()函数无法创建新按钮,我只能删除。如果我摆脱free()函数,malloc()不再失败。所以,我的问题是我是否正确地创建并删除了这些结构?
结构体取自我修改为在我的特定硬件上工作的GUI库。
typedef struct
{
obj_t obj; /**< object structure */
string_t label; /**< button label, NULL if no label */
color_t color; /**< color of the button */
} button_t;
typedef struct obj_t
{
int x; /**< x position, relative to parent */
int y; /**< y position, relative to parent */
unsigned width; /**< component widht */
unsigned height; /**< component height */
draw_t draw; /**< function to draw the component */
handler_t handler; /**< function to handle mouse-input events */
action_t action; /**< function to handle user action */
struct obj_t *parent; /**< parent of the component */
unsigned agui_index; /**< agui structure index */
BOOL enabled; /**< if set, component is enabled */
BOOL visible; /**< */
BOOL invalidated; /**< if set, draw this component */
BOOL invalidated_child; /**< children need to be redrawn */
BOOL selected; /**< component is selected */
BOOL pressed; /**< component is pressed */
uintptr_t tag; /**< tag for general use */
} obj_t;
typedef struct
{
int x; /**< x position */
int y; /**< y position */
char *text; /**< string text */
const font_t *font; /**< string-text font */
color_t color; /**< string-text color */
fontstyle_t fontstyle; /**< string-text font style */
align_t align; /**< alignment with respect to x and y position */
} string_t;
这些是使用malloc()的代码片段:
char *step_name = (char*)malloc(20*sizeof(char));
if(step_name == NULL)
return -1;
sprintf(step_name,"STEP %d",curr_job_recipe->curr_step->step_num);
obj_t *obj_step = (obj_t*) malloc(sizeof(obj_t));
if(obj_step == NULL)
{
free(step_name);
return -1;
}
string_t *label_step = (string_t*) malloc(sizeof(string_t));
if(label_step == NULL)
{
free(step_name);
free(obj_step);
return -1;
}
button_t *newstep_button =(button_t*) malloc(sizeof(button_t));
if(newstep_button == NULL)
{
free(step_name);
free(obj_step);
free(label_step);
return -1;
}
obj_t **objects; // This is a parameter to the function I'm simplifying to save sanity
objects[curr_index] = &newstep_button->obj;
obj_step->x = 2;
obj_step->y = objects[curr_index-1]->y+BUTTON_HEIGHT+1;
obj_step->width = 316;
obj_step->height = 60;
obj_step->draw = button_draw;
obj_step->handler = button_handler;
obj_step->parent = AGUI_HANDLE(editrecipeform);
obj_step->agui_index = 0;
obj_step->action = editrecipeform_btn5_action;
obj_step->visible = TRUE;
obj_step->enabled = TRUE;
obj_step->selected = FALSE;
obj_step->pressed = TRUE;
obj_step->invalidated = TRUE;
label_step->x = 0;
label_step->y = 0;
label_step->text = step_name;
label_step->font = &helveticaneueltstdltext18_2BPP;
label_step->color = BLACK;
label_step->fontstyle = FS_NONE;
label_step->align = ALIGN_CENTRE;
newstep_button->obj = *obj_step;
newstep_button->label = *label_step;
newstep_button->color = RED;
然后,当用户选择按钮上的删除时,执行以下操作。
button_t *newstep_button = (button_t*) objects[i];
obj_t *obj_step = (obj_t*) &newstep_button->obj;
string_t *label_step = (string_t*) &newstep_button->label;
free(label_step->text);
free(label_step);
free(obj_step);
free(newstep_button);
编辑:添加了一些我在malloc()代码空间区域中遗漏的初始化代码
答案 0 :(得分:2)
obj_t *obj_step = (obj_t*) &newstep_button->obj;
free(obj_step);
在这里,您尝试释放非指针结构字段。您不应该这样做:当您调用free
并且不需要单独释放字段时,将释放整个结构的内存。 label
字段也是如此。
如果你的struct有你用malloc
分配的指针字段,你需要在释放struct本身之前单独释放它们。
关于您分配的obj_step
和label_step
变量,您需要释放它们,但是从您发布的代码中不清楚存储其值的位置。如果它们未在任何地方使用,您可以删除这两个malloc
。
编辑:您的初始化代码基本上如下所示:
obj_t *obj_step = (obj_t*) malloc(sizeof(obj_t));
//... set members of obj_step
newstep_button->obj = *obj_step; //this will copy the entire struct
所以你实际上并不需要obj_step
:你可以直接设置newstep_button->obj
的成员,例如:
newstep_button->obj.x = 2;
答案 1 :(得分:0)
我没有看到label_step->text
被设置为任何东西;它可能没有被设置,或被设置为指向未被malloc()
分配的块,而这就是失败的来源。
答案 2 :(得分:0)
您没有将malloc返回的指针存储在button_t对象中。
更改
typedef struct
{
obj_t obj; /**< object structure */
string_t label; /**< button label, NULL if no label */
color_t color; /**< color of the button */
} button_t;
到
typedef struct
{
obj_t *obj; /**< object structure */
string_t *label; /**< button label, NULL if no label */
color_t color; /**< color of the button */
} button_t;
以及init中的这些变化:
newstep_button->obj = obj_step;
newstep_button->label = label_step;
newstep_button->color = RED;
以及免费的这些变化:
button_t *newstep_button = (button_t*) objects[i];
obj_t *obj_step = newstep_button->obj;
string_t *label_step = newstep_button->label;
free(label_step->text);
free(label_step);
free(obj_step);
free(newstep_button);
如果您释放了一些非使用malloc创建的内容,那么您所描述的内容听起来就像是典型的行为。你基本上是在废弃内存分配列表 - 当malloc试图找到一些空闲的内存时它会崩溃。
我必须看到更多的代码才能确定,但是所有的免费陈述似乎都让我怀疑。要确定是否存在问题,请显示为每个语句分配空间的代码:
free(label_step->text);
free(label_step);
free(obj_step);
free(newstep_button);