malloc - 硬故障 - Keil uVision

malloc - Hardfault - Keil uVision

我正在使用 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

您的目标系统 非常 RAM。可能 malloc() 无法满足分配请求,但您没有测试 malloc() 失败。 硬故障 可能是由于您在 scbuf->st_max = size;.

取消引用空指针引起的

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

另请注意这些评论:

  • 如果circular_structbuf_init总是分配一个新结构,它不应该将scbuf作为参数。
  • 您可以使用灵活的数组减少此结构的内存占用:st_array 移动到结构的末尾,只够 space 用于头部和元素的实际数量已分配。

这是修改后的版本:

/*** 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 作为定义的大小。