Как рекурсивно вернуть строковое значение в C? - PullRequest
0 голосов
/ 27 августа 2018

Попытка узнать что-то здесь больше, чем решить конкретную проблему.Пожалуйста, помогите мне с некоторыми лучшими практиками, применимыми в этой ситуации, и, если возможно, поясните, почему.Заранее благодарен за вашу помощь.

По сути, я грубо взломал очень простой алгоритм хеширования в известных пределах.Функция проверяет возможности строки (в пределах длины) с хешем, пока он не совпадет с переданным хешем.Тогда рекурсия должна остановить все итерации и вернуть строку, которая соответствует.Итерация работает, но когда ответ найден, кажется, что при каждом запуске функции не возвращается значение, возвращаемое при вызове одной и той же функции .

Вот кодфункция с дополнительными комментариями для ясности:

//'hash' is the hash to be replicated
//'leading' is for recursive iteration (1st call should have leading=="")
//'limit' is the maximum string length to be tested

string crack(string hash, string leading, int limit)
{
    string cracked=NULL, force=NULL, test=NULL;

    //as per definition of C's crypt function - validated
    char salt[3] = {hash[0], hash[1], '\0'};

    // iterate letters of the alphabet - validated
    for(char c='A'; c<='z'; c++)
    {
        // append c at the end of string 'leading' - validated
        test = append(leading,c);

        // apply hash function to tested string - validated
        force = crypt(test,salt);

        // if hash replicated, store answer in 'cracked' - validated
        if(strcmp(hash,force)==0)
        {
            cracked = test;
        }
        else
        {
            // if within length limit, iterate next character - validated
            if(strlen(test)<=limit+1)
            {
                // THIS IS WHERE THE PROBLEM OCCURS
                // value received when solution found
                // is always empty string ("", not NULL)
                // tried replacing this with strcpy, same result
                cracked = crack_des(hash,test,limit);
            }
        }

        // if answer found, break out of loop - validated
        if(cracked){break;}

        // test only alphabetic characters - validated
        if(c=='Z'){c='a' - 1;}
    }

    free(test);

    // return NULL if not cracked to continue iteration on level below
    // this has something to do with the problem
    return cracked;
} // end of function

Из небольшого количества воспоминаний, которые я помню, я бы предположил, что это что-то с передачей ссылок вместо значений, но у меня недостаточно знаний, чтобыреши это.Я прочитал эту тему , но это предложение, похоже, не решает проблему - я попытался использовать strcpy и получил те же результаты.

Отказ от ответственности: это упражнение в CS50 2018 года отГарвард в EDX.Это не повлияет на мою оценку (уже отправили два идеальных упражнения на неделю, что и требуется), но, как указано выше, я хочу учиться.

Редактировать : отредактированотег обратно в C (как поясняется в комментариях, строка взята из string.h, а append был написан мной и проверен несколько раз - я скоро доберусь до TDD).Спасибо всем за ваши комментарии;проблема решена и уроки извлечены!

1 Ответ

0 голосов
/ 27 августа 2018

Я нашел ошибку в коде, но я не уверен, является ли она основной причиной вашей проблемы.

Когда код попадет в строку:

strcmp(hash,force)==0

, тогда выназначит строку, на которую указывает 'test' значение 'cracked':

cracked = test;

, затем эта строка будет нажата:

if(cracked){break;}

, затем цикл будет разорван, а следующая строка:

free(test);

эта строка освободит строку, указанную тестом, и помните, что это та же строка, на которую указывает 'cracked', таким образом, вы вернули строку, которая уже освобождена .

Что будет со строкой, зависит от вашего компилятора и libc.Вы можете попытаться решить эту проблему, выделив память для «cracked»:

cracked = strdup(test);

Также существуют утечки памяти, вызванные строками 'test' и 'force', но они не должны иметь отношения к вашей проблеме..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...