首页 > 解决方案 > 移动指针后的 Malloc 在 C 中不起作用?

问题描述

我想使用TRIE. 代码的前三部分按预期工作。但是我试图缩短代码的第三部分,然后它不起作用,没有添加nodesTRIE.

这是声明部分:

#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));

标签: cpointersdata-structuresmalloctrie

解决方案


通过执行您所做的操作,您将赋值目标与 中的接收左值“分离” 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;

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


推荐阅读