移动指针后的 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;
(或等效的基于 ?:
的版本)。
我想使用 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;
(或等效的基于 ?:
的版本)。