将字符串传递给init函数并将其存储在malloc'd结构中

时间:2017-09-05 09:23:49

标签: c string char malloc

我正在编写一个init函数来初始化链表中的第一个节点。我正在尝试添加一个字符串名称来标记每个节点,但是当函数返回时会出现奇怪的行为。我将字符串直接传递给函数,mallocing另一个相同长度的char *然后将输入字符串strcpy到这个新位置。我试图将它存储在结构中的char **中。它在init函数中复制到struct中,但是一旦它返回字符串更改,就会在返回init函数时释放内存。

typedef struct {
    key_grid_TypeDef* grid;

    char** name;
    uint8_t ID;

    void* next;
    void* prev;
} keymap_layer;

keymap_err_TypeDef keymap_init( keymap_list* layer_list,
    key_grid_TypeDef* grid, char* layer_name ){

//init initial layer
    keymap_layer *layer = (keymap_layer*) malloc (sizeof(keymap_layer));
    if (layer == NULL)
        return km_init_err;

    char* mal_name = (char*) 
    malloc((strlen(layer_name)+1)*sizeof(char));
    if (mal_name == NULL)
        return km_init_err;
    strcpy(mal_name,layer_name);
    layer->name = &mal_name;

    if(sizeof(keymap0) == sizeof(*layer->grid))
        memcpy(&layer->grid, &grid, KEYBOARD_ROWS * KEYBOARD_COLS);
    else{
        free(layer);
        return km_init_err;
}

return km_ok;}

在我的任务中

ret = keymap_init(&key_layer_list, &keymap0, "Initial layer");

由于

1 个答案:

答案 0 :(得分:0)

这非常可疑:

char* mal_name = (char*) malloc((strlen(layer_name)+1)*sizeof(char));
if (mal_name == NULL)
    return km_init_err;
strcpy(mal_name,layer_name);
layer->name = &mal_name;

一旦mal_name函数终止,局部变量keymap_init就不再存在,因此您存储了一个指向该变量的指针。

你应该这样做:

typedef struct {
    ...    
    char* name;   // just a simple pointer to char
    ...
} keymap_layer;

...
layer->name = malloc((strlen(layer_name)+1)*sizeof(char));
strcpy(layer->name, layer_name);

如果您想稍后更改layer->name中存储的字符串,请使用realloc

例如:

...
layer->name = realloc(layer->name, (strlen(new_name)+1)*sizeof(char));
strcpy(layer->name, new_name);
...

Disclamer:为简洁起见,没有错误检查。

顺便说一句:你没有强制转换mallocfriends的返回值。