【发布时间】:2021-08-01 06:13:13
【问题描述】:
我在 Linux 上运行的代码没有内存错误,并且在 Linux 上运行时树可以正确构建,但是当我在 Windows 上运行它时它会卡住并终止。
struct node {
char letter;
char *string;
int last_node;
struct node *left;
struct node *right;
};
static struct node nodes[] =
{
{'\0', ""},
{'E', "."},
{'T', "-"},
{'I', ".."},
{'A', ".-"},
{'N', "-."},
{'M', "--"},
{'S', "..."},
{'U', "..-"},
{'R', ".-."},
{'W', ".--"},
{'D', "-.."},
{'K', "-.-"},
{'G', "--."},
{'O', "---"},
{'H', "...."},
{'V', "...-"},
{'F', "..-."},
{'\0', "..--"},
{'L', ".-.."},
{'\0', ".-..-"},
{'P', ".--."},
{'J', ".---"},
{'B', "-..."},
{'X', "-..-"},
{'C', "-.-."},
{'Y', "-.--"},
{'Z', "--.."},
{'Q', "--.-"},
{'\0', "---."},
{'\0', "----"},
{'5', "....."},
{'4', "....-"},
{'\0', "...-."},
{'3', "...--"},
{'\0', "..-.."},
{'\0', "..-.-"},
{'\0', "..--."},
{'2', "..---"},
{'\0', ".-..."},
{'\0', ".-..-"},
{'\0', ".-.-."},
{'\0', ".-.--"},
{'\0', ".--.."},
{'\0', ".--.-"},
{'\0', ".---."},
{'1', ".----"},
{'6', "-...."},
{'\0', "-...-"},
{'/', "-..-."},
{'\0', "-..--"},
{'\0', "-.-.."},
{'\0', "-.-.-"},
{'\0', "-.--."},
{'\0', "-.---"},
{'7', "--..."},
{'\0', "--..-"},
{'\0', "--.-."},
{'\0', "--.--"},
{'8', "---.."},
{'\0', "---.-"},
{'9', "----."},
{'0', "-----"},
{.last_node = 1}
};
struct node *
tree_insert(struct node *root, struct node *selnode_addr, char *string)
{
if (string[0] == '.')
{
if (string[1] == 0)
{
return root -> left = selnode_addr;
}
return tree_insert(root -> left, selnode_addr, string + 1);
}
if (string[1] == 0)
{
return root -> right = selnode_addr;
}
return tree_insert(root -> right, selnode_addr, string + 1);
}
int
main(void)
{
// constructs the binary tree.
for (struct node *nodeptr = nodes + 1; !nodeptr -> last_node; nodeptr++)
{
tree_insert(nodes, nodeptr, nodeptr -> string);
}
puts("test");
return 0;
}
在 Linux 上,它运行并打印 'test' 并通过 valgrind,没有内存错误,我在 GDB 中验证了树构建正确,但在 Windows 上它会挂起一小段时间,然后似乎崩溃了。我不知道为什么。
更新
- 编译器是 gcc (MinGW.org GCC Build-2) 9.2.0
- 我尝试了
-std=c99 -pedantic,但也没有用。 - Braden Best 建议删除树底部的空节点,然后它就起作用了。下面提供了新的工作树。
新数组:
static struct node nodes[] =
{
{'\0', ""},
{'E', "."},
{'T', "-"},
{'I', ".."},
{'A', ".-"},
{'N', "-."},
{'M', "--"},
{'S', "..."},
{'U', "..-"},
{'R', ".-."},
{'W', ".--"},
{'D', "-.."},
{'K', "-.-"},
{'G', "--."},
{'O', "---"},
{'H', "...."},
{'V', "...-"},
{'F', "..-."},
{'\0', "..--"},
{'L', ".-.."},
{'P', ".--."},
{'J', ".---"},
{'B', "-..."},
{'X', "-..-"},
{'C', "-.-."},
{'Y', "-.--"},
{'Z', "--.."},
{'Q', "--.-"},
{'\0', "---."},
{'\0', "----"},
{'5', "....."},
{'4', "....-"},
{'3', "...--"},
{'2', "..---"},
{'1', ".----"},
{'6', "-...."},
{'/', "-..-."},
{'7', "--..."},
{'8', "---.."},
{'9', "----."},
{'0', "-----"},
{.last_node = 1}
};
【问题讨论】:
-
windows 很可能没有将数组中未提及的其余字段初始化为 NULL。
-
样式指南:点
.和箭头->运算符绑定非常紧密,因为它们是 postfix operators。它们不应该被写成周围有空格。写root -> left不是惯用的C 语言,表示编码器是一个tyro(新手)。使用root->left。 -
有趣的是,代码中没有动态内存分配。使用预先存在的
nodes数组。因为数组是在任何函数之外定义的,所以初始化器中未明确列出的任何元素都将归零(空指针)。 -
@bruceg 你确定吗?数组是静态的。我知道 Windows 可能很糟糕,但
static对象尤其保证默认为零。更不用说,部分定义中留空的元素保证会被清零。例如,static char array[32];和char array[32] = "p";保证分别为 32 个零和 p 后跟 31 个零 -
用 gcc 7.5.0-3ubuntu1~18.04 测试,
-Wall -Wextra -g -Wno-missing-field-initializers,在 tree_insert 的 valgrind 中发现了一个错误。它似乎在 0x18 找到了一个地址并尝试取消引用它,即未定义的行为。有趣的是,当我第一次测试它时,我已经从树的底部删除了所有节点,让它们为空,因为我认为它们是不必要的,并且代码运行良好,没有内存错误。我让 sinan 尝试删除这些节点,这对他也有效
标签: c linux windows data-structures binary-tree