在 malloc() 之后使用 memset() 会导致断言

问题描述 投票:0回答:1

我有一个这样的结构:

struct state {
    bool isfinal;
    bool *isfull;
    char **board;
};

isfull
是一个数组,
board
是一个二维数组。

我可以使用此函数为数组分配内存:

struct state new_state(struct state state)
{
    int i;
    struct state new_state = {};
    new_state.isfull = (bool *) malloc(BOARD_WIDTH *sizeof (bool));
    new_state.board = (char **) malloc(BOARD_HIGHT *sizeof (char *));
    for (i = 0; i < BOARD_HIGHT; ++i)
        new_state.board[i] = (char *) malloc(BOARD_WIDTH *sizeof (char));
    if (state.board) {
        memcpy(new_state.isfull, state.isfull, BOARD_WIDTH * sizeof (bool));
        memcpy(new_state.board, state.board, BOARD_HIGHT + BOARD_HIGHT * BOARD_WIDTH);
    } else {
        getchar();
        memset(new_state.isfull, 0, BOARD_WIDTH * sizeof (bool));
        for (i = 0; i < BOARD_HIGHT; ++i)
            memset(new_state.board[i], 0, BOARD_HIGHT * sizeof (char *));
    }
    return new_state;
}

第一次使用 0 调用该函数,else 块将被执行。 这会产生一个断言。 同样,在断言的情况下,函数会执行到 return 语句,然后程序才会中断。

我已经通过使用 calloc() 解决了这个问题。 这有效:

struct state new_state(struct state state)
{
    int i;
    struct state new_state = {};
    new_state.isfull = (bool *) calloc(BOARD_WIDTH ,sizeof (bool));
    new_state.board = (char **) calloc(BOARD_HIGHT ,sizeof (char *));
    for (i = 0; i < BOARD_HIGHT; ++i)
        new_state.board[i] = (char *) calloc(BOARD_WIDTH ,sizeof (char));
    if (state.board) {
        memcpy(new_state.isfull, state.isfull, BOARD_WIDTH * sizeof (bool));
        memcpy(new_state.board, state.board, BOARD_HIGHT + BOARD_HIGHT * BOARD_WIDTH);
    } else {
        // memset(new_state.isfull, 0, BOARD_WIDTH * sizeof (bool));
        // for (i = 0; i < BOARD_HIGHT; ++i)
        //     memset(new_state.board[i], 0, BOARD_HIGHT * sizeof (char *));
    }
    return new_state;
}

有趣的是,使用 getchar() 函数作为延迟形式也有效! 像这样:

struct state new_state(struct state state)
{
    int i;
    struct state new_state = {};
    new_state.isfull = (bool *) malloc(BOARD_WIDTH *sizeof (bool));
    new_state.board = (char **) malloc(BOARD_HIGHT *sizeof (char *));
    for (i = 0; i < BOARD_HIGHT; ++i)
        new_state.board[i] = (char *) malloc(BOARD_WIDTH *sizeof (char));
    if (state.board) {
        memcpy(new_state.isfull, state.isfull, BOARD_WIDTH * sizeof (bool));
        memcpy(new_state.board, state.board, BOARD_HIGHT + BOARD_HIGHT * BOARD_WIDTH);
    } else {
        getchar();
        memset(new_state.isfull, 0, BOARD_WIDTH * sizeof (bool));
        for (i = 0; i < BOARD_HIGHT; ++i)
            memset(new_state.board[i], 0, BOARD_HIGHT * sizeof (char *));
    }
    return new_state;
}

搜索互联网,我发现在 malloc() 之后使用 memset() 是一种常见的做法。 所以第一个问题:为什么我的函数的第一个版本不起作用? 第二:为什么使用 getchar() 使它起作用?

c memory-management malloc memset
1个回答
0
投票

看起来像是一个错字,你使用的是:

memset(new_state.board[i], 0, BOARD_HIGHT * sizeof (char *));

而不是:

memset(new_state.board[i], 0, BOARD_WIDTH * sizeof (char *));

如果

BOARD_HIGHT != BOARD_WIDTH
那么你可以让元素未初始化(并且具有不确定的值),否则你将超出界限并具有明确的未定义行为。

我假设您复制粘贴了

memset
调用,但忘记更改此设置。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.