如何调试在调试器中工作的C代码?

时间:2014-06-05 12:26:33

标签: c gdb initialization lldb

我有以下C代码

double ComputeWord (String* word, List* dict, List* words, Matrix* results, String* ret) {
    int i = 0;
    signed long wordIndex = ListFind (words, (void*)word);
    double min = StringSize (word); // Largest possible cost
    int minIndex = 0;
    if (wordIndex == ListEnd (words) ) { 
        ListAppend(words, (void*) word);
        wordIndex = ListSize(words) - 1;
        MatrixExpand (results, 0, ListSize(words));
    }
    for (i = 0; i < ListSize(dict); i++) {
        if (!strcmp (CString(word), CString( (String*)ListElement(dict, i) ) ) ) { min = 0; minIndex = i; break; }
        double current = fromDatabase ((long)MatrixElement(results, i, wordIndex) );
        if (current == 0) {
            printf ("Was not processed\n");
            current = lDist (word, ListElement(dict, i) );
            MatrixSetElement (results, (void*)toDatabase(current), i, wordIndex);
        }
        if (current <= min) { min = current; minIndex = i; }
        printf ("%s to %s - %.1lf\n", word->elementArray, ((String*)ListElement (dict,     i))->elementArray, current);
    }

    String temp;
    StringInit (&temp);
    char temp2[256];

    sprintf (temp2, ",%.1lf", min);

    StringSet (&temp, temp2);

    StringConcatenate(ret, (String*) ListElement (dict, minIndex) );
    StringConcatenate(ret, &temp);

    StringDelete (&temp);
    StringAppend(ret, ' ');
    printf ("matched %s to %s - %.1lf\n", word->elementArray, ((String*)ListElement (dict, minIndex))->elementArray, min);
    return min;
}                                                                  

它的作用是使用字典词典和单词并尝试使用demerau-levenshtein距离(lDist)匹配字典中的单词,然后将结果存储在矩阵中。

发生的事情是,当我的算法正确计算距离时,它认为某些单词已经存储,所以它得到了错误。 我尝试打开GDB试图弄清楚发生了什么,但程序在其中正确运行。

我得到的结果是:

creating dictionary
adding aspecto to dict
adding matematica to dict
adding algebra to dict
adding posicao to dict
adding profissao to dict
adding fourier to dict
adding casa to dict
adding calculo to dict
adding dificil to dict
Was not processed
aepscto to aspecto - 3.0
Was not processed
aepscto to matematica - 9.5
Was not processed
aepscto to algebra - 8.5
Was not processed
aepscto to posicao - 5.5
Was not processed
aepscto to profissao - 9.0
Was not processed
aepscto to fourier - 10.5
Was not processed
aepscto to casa - 6.5
Was not processed
aepscto to calculo - 7.0
Was not processed
aepscto to dificil - 9.0
matched aepscto to aspecto - 3.0
Was not processed
caculo to aspecto - 6.5
Was not processed
caculo to matematica - 11.0
Was not processed
caculo to algebra - 8.5
Was not processed
caculo to posicao - 7.0
Was not processed
caculo to profissao - 10.5
Was not processed
caculo to fourier - 9.0
Was not processed
caculo to casa - 5.0
Was not processed
caculo to calculo - 1.0
Was not processed
caculo to dificil - 7.5
matched caculo to calculo - 1.0
Was not processed
matmatica to aspecto - 10.0
Was not processed
matmatica to matematica - 1.0
Was not processed
matmatica to algebra - 9.5
Was not processed
matmatica to posicao - 8.5
Was not processed
matmatica to profissao - 11.5
Was not processed
matmatica to fourier - 11.0
Was not processed
matmatica to casa - 8.0
Was not processed
matmatica to calculo - 10.5
Was not processed
matmatica to dificil - 10.0
matched matmatica to matematica - 1.0
augebra to aspecto - 6.5
augebra to matematica - 11.0
augebra to algebra - 8.5
augebra to posicao - 7.0
augebra to profissao - 10.5
augebra to fourier - 9.0
augebra to casa - 5.0
augebra to calculo - 1.0
augebra to dificil - 7.5
matched augebra to calculo - 1.0

我注意到&#34; augebra&#34;与&#34; caculo&#34;完全相同,这意味着ListFind正在返回&#34; caculo&#34;的索引,但这应该是不可能的,因为我直接使用strcmp为此

/* Method: StringListComp
 * Parameters:
 * a - First String
 * b - Second String
 * Return value:
 * a == b
 * Description:
 * A specialization of list compare for strings. Compares the strings and returns.
 */

Bool StringListCompare (void* a, void* b) {
    return (Bool)!strcmp ( ( (String*)a)->elementArray, ( (String*)b)->elementArray);
}


/* Method: ListFind                                                                                                                                                                                         
 * Parameters:
 * list - List to search
 * element - Element to find
 * Return value:
 * Returns element if it was found and ListEnd if not.
 * Description:
 * Search list for element.
 */

uintptr_t ListFind (List* list, void* element) {
    uintptr_t i;
    for (i = 0; i < list->size; i++) {
        if ( list->ListCompare(list->elementArray[i], element) ) return i;
    }
    return ListEnd (list);
}

这怎么可能?

编辑: 我想我可能已经找到了这个问题。

当我调用这样的方法时:

    for (i = 0; i < ListSize(&workingStudent); i++) {
        score += ComputeWord (ListElement(&workingStudent, i), &dict, &words, &results, &ret);
        StringDelete ((String*)ListElement (&workingStudent, i);
    }

我将删除我发送到行

列表中的字符串
ListAppend(words, (void*) word);

由于word是指针,字符串会被删除,列表也不知道。 这样,String中的char *开始指向可以更改的空闲内存位置。

1 个答案:

答案 0 :(得分:0)

发生的事情是调试器不允许更改释放的内存,因此它保留了删除的单词。但现实世界的记忆并非如此。 解决此问题的方法是删除删除字符串的行并将其添加到代码中:

if (wordIndex == ListEnd (words) ) { 
    ListAppend(words, (void*) word);
    wordIndex = ListSize(words) - 1;
    MatrixExpand (results, 0, ListSize(words));
//==========\/This\/==========//
} else {
    StringDelete (word);
    free (word);
    word = (String*) ListElement (words, wordIndex);
}

所以当没有必要时,word会被删除,并开始指向已经缓存的单词。 请注意调试器及其不必要的数据正确性。