【问题标题】:String memory issue: printing a string with printf seems to overwrite itself字符串内存问题:使用 printf 打印字符串似乎会覆盖自身
【发布时间】:2016-01-19 03:59:33
【问题描述】:

我开始使用 MIT OCW 入门课程学习 C(该课程可以在 here 找到)。我正在完成其中一项作业,您必须编写函数以使用给定的模板(在名为 prob2.c 的文件中找到 here)将 trie 结构实现为英法词典。基本上,该程序应该要求翻译一个单词,在 trie 中查找它,然后给出翻译。我第一次尝试自己实现它,但我一直遇到一个错误,结果似乎是“打印”本身。这是正在发生的事情的一个例子,因为解释起来有点奇怪:

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 上发布的解决方案再次编译,似乎没有任何变化。我尝试使用 valgrind 运行该程序,看看是否有任何明显的内存问题可以解释这一点,但在查找单词时没有出现任何问题,只是在最后释放 trie 时出现了一些问题。

这是我怀疑可能是主要问题的功能(这是我在帖子前面链接的解决方案):

/* 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;
}

如果有人能向我解释为什么会发生这种情况以及如何解决它,我将不胜感激!

【问题讨论】:

    标签: c string malloc trie


    【解决方案1】:

    您的翻译以 CRLF 结尾输入,但解析代码正在寻找 LF 终止符。因此,每个翻译的末尾都有一个 CR,就在add_word 添加的逗号之前。因此,当您打印它们时,CR 会使它们在屏幕的左边缘一个叠印。

    add_word 中添加测试以确认这一点。

    if (pnode->translation[oldlen-1] == '\r') ...
    

    【讨论】:

    • 啊,行尾疯狂的乐趣。
    • 测试了一下,你是对的。现在只需对 load_dictionary() 函数稍作调整,以在换行符之后切断回车符。如此简单的修复,完全认为答案将是令人讨厌的复杂。非常感谢!
    猜你喜欢
    • 2017-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2013-03-09
    • 2012-08-22
    • 1970-01-01
    相关资源
    最近更新 更多