字符串内存问题:使用 printf 打印字符串似乎会覆盖自身
String memory issue: printing a string with printf seems to overwrite itself
我开始使用 MIT OCW 入门课程学习 C(课程可以在名为 prob2.c 的文件中找到 here). I am going through one of the assignments in which you have to write functions to implement a trie structure as an English-to-French dictionary using the given template (found here)。基本上,该程序应该要求翻译一个单词,在 trie 中查找它,然后给出翻译。我首先尝试自己实现它,但我让 运行 陷入错误,结果似乎是在打印 "over" 本身。这是一个正在发生的事情的例子,因为解释起来有点奇怪:
Enter word to translate: Adam
,Adamo> Adam
Enter word to translate: word
,parole mot
Enter word to translate: hello
,eh oh-> salut
Enter word to translate: tree
tree -> arbre
对于这些输入,它应该看起来像这样,以便翻译仅由逗号分隔:
Enter word to translate: Adam
Adam -> Adam,Adamo
Enter word to translate: word
word -> mot,parole
Enter word to translate: hello
hello -> salut,allo,eh oh
Enter word to translate: tree
tree -> arbre
放弃并查看解决方案后(找到 here,请参阅问题 6.2,完整的问题描述也包括在内),我的代码与给出的代码没有太大区别。无论如何,我使用 OCW 上的 posted 解决方案再次编译,似乎没有任何变化。我用 valgrind 尝试了 运行 程序,看看是否有任何明显的内存问题可以解释这一点,但是在查找单词时没有出现任何问题,只是在最后释放 trie 时出现了一些问题。
这是我怀疑可能是主要问题的函数(这是我之前在 post 中链接的解决方案):
/* add word to trie, with translation
input: word and translation
output: non-zero if new node added, zero otherwise
postcondition: word exists in trie */
int add_word(const char *word, char *translation) {
struct s_trie_node *pnode = proot;
int i, len = strlen(word), inew = 0;
unsigned char j;
for (i = 0; i < len; i++) {
j = word[i];
if ((inew = !pnode->children[j]))
pnode->children[j] = new_node();
pnode = pnode->children[j];
}
if (pnode->translation) {
/* concatenate strings */
char *oldtranslation = pnode->translation;
int oldlen = strlen(oldtranslation), newlen = strlen(translation);
pnode->translation = malloc(oldlen + newlen + 2);
strcpy(pnode->translation, oldtranslation);
strcpy(pnode->translation + oldlen, ",");
strcpy(pnode->translation + oldlen + 1, translation);
free(oldtranslation);
} else
pnode->translation = strcpy(malloc(strlen(translation) + 1), translation);
return inew;
}
如果有人能向我解释为什么会发生这种情况以及如何解决它,我将不胜感激!
您输入的翻译以 CRLF 结尾,但解析代码正在寻找 LF 终止符。因此,每个翻译的末尾都有一个 CR,就在 add_word
添加的逗号之前。因此,当您打印它们时,CR 会使它们在屏幕的左边缘一个接一个地打印。
在 add_word
中添加测试以确认这一点。
if (pnode->translation[oldlen-1] == '\r') ...
我开始使用 MIT OCW 入门课程学习 C(课程可以在名为 prob2.c 的文件中找到 here). I am going through one of the assignments in which you have to write functions to implement a trie structure as an English-to-French dictionary using the given template (found here)。基本上,该程序应该要求翻译一个单词,在 trie 中查找它,然后给出翻译。我首先尝试自己实现它,但我让 运行 陷入错误,结果似乎是在打印 "over" 本身。这是一个正在发生的事情的例子,因为解释起来有点奇怪:
Enter word to translate: Adam
,Adamo> Adam
Enter word to translate: word
,parole mot
Enter word to translate: hello
,eh oh-> salut
Enter word to translate: tree
tree -> arbre
对于这些输入,它应该看起来像这样,以便翻译仅由逗号分隔:
Enter word to translate: Adam
Adam -> Adam,Adamo
Enter word to translate: word
word -> mot,parole
Enter word to translate: hello
hello -> salut,allo,eh oh
Enter word to translate: tree
tree -> arbre
放弃并查看解决方案后(找到 here,请参阅问题 6.2,完整的问题描述也包括在内),我的代码与给出的代码没有太大区别。无论如何,我使用 OCW 上的 posted 解决方案再次编译,似乎没有任何变化。我用 valgrind 尝试了 运行 程序,看看是否有任何明显的内存问题可以解释这一点,但是在查找单词时没有出现任何问题,只是在最后释放 trie 时出现了一些问题。
这是我怀疑可能是主要问题的函数(这是我之前在 post 中链接的解决方案):
/* add word to trie, with translation
input: word and translation
output: non-zero if new node added, zero otherwise
postcondition: word exists in trie */
int add_word(const char *word, char *translation) {
struct s_trie_node *pnode = proot;
int i, len = strlen(word), inew = 0;
unsigned char j;
for (i = 0; i < len; i++) {
j = word[i];
if ((inew = !pnode->children[j]))
pnode->children[j] = new_node();
pnode = pnode->children[j];
}
if (pnode->translation) {
/* concatenate strings */
char *oldtranslation = pnode->translation;
int oldlen = strlen(oldtranslation), newlen = strlen(translation);
pnode->translation = malloc(oldlen + newlen + 2);
strcpy(pnode->translation, oldtranslation);
strcpy(pnode->translation + oldlen, ",");
strcpy(pnode->translation + oldlen + 1, translation);
free(oldtranslation);
} else
pnode->translation = strcpy(malloc(strlen(translation) + 1), translation);
return inew;
}
如果有人能向我解释为什么会发生这种情况以及如何解决它,我将不胜感激!
您输入的翻译以 CRLF 结尾,但解析代码正在寻找 LF 终止符。因此,每个翻译的末尾都有一个 CR,就在 add_word
添加的逗号之前。因此,当您打印它们时,CR 会使它们在屏幕的左边缘一个接一个地打印。
在 add_word
中添加测试以确认这一点。
if (pnode->translation[oldlen-1] == '\r') ...