首页 文章

结构和malloc()/ free()的麻烦

提问于
浏览
2

我正在尝试将双向链表映射到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()代码空间区域中遗漏的初始化代码

3 回答

  • 2
    obj_t *obj_step = (obj_t*) &newstep_button->obj;
    free(obj_step);
    

    在这里,您尝试释放非指针结构字段 . 当你调用 free 并且不需要分别释放字段时,你不应该释放内存 . 对于 label 字段也是如此 .

    如果您的结构具有使用 malloc 分配的指针字段,则需要在释放结构本身之前单独释放它们 .

    关于您分配的 obj_steplabel_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;
    
  • 0

    我没有看到 label_step->text 被置于任何东西;它没有被设置,或被设置为指向未被 malloc() 分配的块,而这是失败的来源 .

  • 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);
    

相关问题