移动指针后的 Malloc 在 C 中不起作用?

Malloc after moving the pointer doesn't work in C?

我想使用 TRIE 加载字典。代码的前三部分按预期工作。但是我试着缩短第三部分的代码,然后它没有用,没有将nodes添加到TRIE

这里是声明部分:

#define ALPHABET_SIZE 27

// define a node for a TRIE.
struct node
{
    _Bool end_of_word;
    struct node *next[ALPHABET_SIZE];
};

// create a TRIE
struct node *root = malloc(sizeof(struct node));

// create a mover.
struct node *mover = root;

// read dictionary file
FILE *dictptr = fopen(dictionary, "r");

主要内容从这里开始:

//load dictionary word by word;
char c;
while ((c = fgetc(dictptr)) != EOF)
{
    if (c == '\n')
    {
        mover->end_of_word = 1;
        mover = root;
    }

这是我要优化的地方:

    else
    {
        if (c == '\'')
        {
            mover->next[ALPHABET_SIZE - 1] = malloc(sizeof(struct node));
            mover = &mover->next[ALPHABET_SIZE - 1];
        }
        else
        {
            mover->next[c - 97] = malloc(sizeof(struct node));
            mover = &mover->next[c - 97];
        }


        // check if memory allocation is successful.
        if (mover == NULL)
        {
            unload();
            fprintf(stderr, "unable to allocate memory to new node.\n");
            return false;
        }
    }

这是我优化的内容:

    else
    {
        if (c == '\'')
        {
            mover = &mover->next[ALPHABET_SIZE - 1];
        }
        else
        {
            mover = &mover->next[c - 97];
        }
        mover = malloc(sizeof(struct node));

通过执行您所做的操作,您 "detached" 从 mover->next[...] 中的接收者左值赋值的目标,从而破坏了代码的原始功能。在您的版本中 mover->next[...] 保持不变。

如果真的想消除这里的代码重复,可以按如下方式做一些事情

    struct node **pmover;

    if (c == '\'')
      pmover = &mover->next[ALPHABET_SIZE - 1];
    else
      pmover = &mover->next[c - 97];

    mover = *pmover = malloc(sizeof(struct node));

这将是您意图的字面实现,也可以重写为

    struct node **pmover = &mover->next[c == '\'' ? ALPHABET_SIZE - 1 : c - 97];
    mover = *pmover = malloc(sizeof(struct node));

虽然我认为更好的主意是

    struct node *new_node = malloc(sizeof(struct node));

    if (c == '\'')
      mover->next[ALPHABET_SIZE - 1] = new_node;
    else
      mover->next[c - 97] = new_node;

    mover = new_node;

(或等效的基于 ?: 的版本)。