【问题标题】:malloc - Hardfault - Keil uVisionmalloc - 硬故障 - Keil uVision
【发布时间】:2020-11-10 11:40:41
【问题描述】:

我正在使用 72kB 闪存和 16kB RAM 控制器。 IDE:Keil uVision v5.29 IDE。

我正在创建一个循环缓冲区,它是一个指向结构的指针。

malloc 正在创建一个硬故障。代码:

/*** Header File *****/


typedef struct circular_structbuf_t circular_structbuf_t;

typedef circular_structbuf_t* scbuf_handle_t;

/****** C file *****/
struct main_struct
{
    int data;
    char char_data;
}

struct circular_structbuf_t
{
    struct  main_struct st_array[128];
    uint8_t st_head;
    uint8_t st_tail;
    uint8_t st_max; //of the buffer
    bool st_full;
};


scbuf_handle_t circular_structbuf_init(scbuf_handle_t scbuf, size_t size)
{
    scbuf = malloc(sizeof(circular_structbuf_t));                       // Causes Hardfault
    scbuf->st_max = size;
    circular_structbuf_reset(scbuf);
    return scbuf;
}


/** Main File ***/
scbuf_handle_t p_cbuf;


int main(void)
{
    p_cbuf=circular_structbuf_init(p_cbuf,50);
    
}

调试时,p_cbuf的地址被分配为0x0

【问题讨论】:

    标签: struct malloc keil circular-buffer


    【解决方案1】:

    您的目标系统的内存非常少。 malloc() 可能无法满足分配请求,但您没有测试 malloc() 失败。 硬故障可能是由于您在 scbuf->st_max = size; 处取消引用空指针。

    尝试减小结构大小,减少 st_array 中的条目数,检查 malloc() 是否返回 NULL 并使用您拥有的任何通信方式发出此错误信号。您可能还需要调整堆栈大小和堆大小。

    还要注意这些备注:

    • 如果circular_structbuf_init 总是分配一个新结构,则不应将scbuf 作为参数。
    • 您可以使用灵活的数组来减少此结构的内存占用:st_array 被移动到结构的末尾,并且只为头部和实际数量的元素分配了足够的空间。

    这是修改后的版本:

    /*** Header File *****/
    
    typedef struct circular_structbuf_t circular_structbuf_t;
    
    typedef circular_structbuf_t *scbuf_handle_t;
    
    /****** C file *****/
    
    struct main_struct {
        int data;
        char char_data;  // if `int` is aligned, there will be some padding after this field
    };
    
    struct circular_structbuf_t {
        uint8_t st_head;
        uint8_t st_tail;
        uint8_t st_max; // of the buffer
        bool st_full;   // type bool is assumed to be a `uint8_t`
        struct main_struct st_array[];  // flexible array syntax
    };
    
    scbuf_handle_t circular_structbuf_init(size_t size) {
        scbuf_handle_t scbuf; 
        scbuf = malloc(sizeof(circular_structbuf_t) + size * sizeof(struct main_struct));
        if (scbuf) {
            scbuf->st_max = size;       
            circular_structbuf_reset(scbuf);
        }
        return scbuf;
    }
    
    /** Main File ***/
    
    scbuf_handle_t p_cbuf;
    
    int main(void) {
        p_cbuf = circular_structbuf_init(50);
        if (p_cbuf == NULL) {
            /* report the error */
        }
        ...
        return 0;
    }
    

    如果你的编译器不支持灵活数组,你可以定义st_array

    struct main_struct st_array[0];
    

    如果编译器也拒绝此替代方案,请使用1 作为定义的大小。

    【讨论】:

    • 感谢您的回复。我显然没有在scbuf = malloc(sizeof(circular_structbuf_t)); 处遇到硬故障,而是在取消引用:circular_structbuf_reset(scbuf); 将值 0 分配给成员 st_headst_tail 。增加了堆大小和堆栈大小 0x800。这现在已经奏效,避免了硬故障。但是以后会有问题吗?
    • @ATHMESHANDROID:我用更多的评论和建议更新了答案
    • 非常感谢。我将根据此修改代码并进行审核。
    猜你喜欢
    • 1970-01-01
    • 2012-03-25
    • 1970-01-01
    • 2019-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    相关资源
    最近更新 更多