Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.08.2024, 15:29   #1
Willy53
Новичок
Джуниор
 
Регистрация: 12.08.2024
Сообщений: 2
По умолчанию Утечка памяти и падение при вызове free()

Приветствую. Есть нижеуказанный код на 100 строк. Это результат портирования операции хеширования с другого языка. Работает отлично (ожидаемый и фактический хеш совпадают), однако если тестить на мемлик - память течёт. Сказывается отсутствие моего опыта в С.

В сети я нашёл информацию о том, что free() вызывается после malloc и ей подобных функций. В моём случае есть только malloc. Она выделяет память под 2 переменные которые я освобождаю в строках 90-91
Код:
    free(hashed);
    free(hexResult);
Однако это вызывает падение
Код:
Process finished with exit code -1073740940 (0xC0000374)
Подскажите пожалуйста, какие именно переменные мне нужно освобождать в этом коде?

P.S. 2 вызова free() и 2 for в main() добавлены исключительно для отлова мемлика и попытки его убрать. В боевых условиях код работает без этого, с раскомментированными printf.
P.P.S. Я бы рад вникать во все тонкости С, однако он мне бывает нужен для таких небольших софтин раз в 10 лет. Поэтому просто надеюсь что кто-то ткнёт пальцем в нужное место и я пойду дальше.

Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int ecnrypt_symbol (int param1, const int param2) {
    if (param2 > 0 && param2 < 9)
    {
        for (int index = 0; index < param2; ++index)
        {
            const int num = param1 & 128U;
            param1 &= 127;
            param1 <<= 1;
            if (num == 0)
                param1 &= 254;
            else
                param1 |= 1;
        }
    }
    return param1;
}

char * replace_by_pos(const char * input, const int pos, const char replace)
{

    char * output = (char*)malloc(strlen(input));

    for (int i = 0; i < strlen(input); i++)
    {
        if (i == pos) output[i] = replace;
        else output[i] = input[i];
    }

    output[strlen(input)] = '\0';

    return output;
}

char * encrypt_string(char *hashed, const char *keyPhraseMaybe, const int unknownInt, const int passBlockLen) {
    for (int index = 0; index < passBlockLen; ++index) {
        const int encParam1 = (int) hashed[index] ^ (int) keyPhraseMaybe[index] ^ (int) unknownInt;
        const int encParam2 = (index + 1) % 8U;

        const unsigned char x = ecnrypt_symbol(encParam1, encParam2);

        hashed = replace_by_pos(hashed, index, x);
    }
    return hashed;
}

char * stringToHexString(const char *text) {
    const int text_len = strlen(text);
    char *hex_output = malloc(text_len*2 + 1);

    int hex_index = 0;

    for (int i = 0; i < strlen(text); i++)
    {
        const unsigned char t = text[i];

        const int w = sprintf(&hex_output[hex_index], "%02X", t);

        if (w < 0)
        {
            perror("Failed to convert to hex.");
            return hex_output;
        }

        hex_index += 2;
    }

    hex_output[strlen(hex_output)] = 0x0;


    return hex_output;
}

int comparePasswordAndHash(const char *password, const char *checkHexString) {
    const int passBlockLen =  8;
    char *hashed = "\x20\x20\x20\x20\x20\x20\x20\x20";
    for (int index = 0; index < strlen(password); ++index) {
        hashed = replace_by_pos(hashed, index, password[index]);
    }

    hashed = encrypt_string(hashed, "ENC_KEY_HERE_REMOVED", 1, passBlockLen);

    char * hexResult = stringToHexString(hashed);

    int result = strcmp(hexResult, checkHexString);
    free(hashed);
    free(hexResult);
    return result;
}
int main(void) {
    printf("Wait \n");
    sleep(3);
    printf("Start \n");

    const char *password = "1234";
    const char * checkHexString = "FA710A648892A940";

    for (int j = 0; j < 2; j++) {
        for (int i = 0; i < 90000000; i++) {
            if (comparePasswordAndHash(password, checkHexString) == 0) {
                // printf("Yes!\n");
            } else {
                // printf("No\n");
            }
        }
    }

    return 0;
}

Последний раз редактировалось Willy53; 12.08.2024 в 15:34.
Willy53 вне форума Ответить с цитированием
Старый 12.08.2024, 17:10   #2
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,343
По умолчанию

Предлагаю отказаться от replace_by_pos, чтобы постоянно не выделять и освобождать память, и работать в буфере hashed. По дороге еще пофиксил другие баги.
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define MIN(x, y) (((x) < (y)) ? (x) : (y))

int ecnrypt_symbol(int param1, const int param2) {
    if (param2 > 0 && param2 < 9)
    {
        for (int index = 0; index < param2; ++index)
        {
            const int num = param1 & 128U;
            param1 &= 127;
            param1 <<= 1;
            if (num == 0)
                param1 &= 254;
            else
                param1 |= 1;
        }
    }
    return param1;
}

void encrypt_string(char *hashed, const char *keyPhraseMaybe, const int unknownInt, const int passBlockLen) {
    for (int index = 0; index < passBlockLen; ++index) {
        const int encParam1 = (int) hashed[index] ^ (int) keyPhraseMaybe[index] ^ (int) unknownInt;
        const int encParam2 = (index + 1) % 8U;

        const unsigned char x = ecnrypt_symbol(encParam1, encParam2);
        hashed[index] = x;
    }
}

char *stringToHexString(const char *text) {
    const int text_len = strlen(text);
    char *hex_output = malloc(text_len * 2 + 1);

    int hex_index = 0;

    for (int i = 0; i < text_len; i++)
    {
        const unsigned char t = text[i];

        const int w = sprintf(&hex_output[hex_index], "%02X", t);

        if (w < 0)
        {
            perror("Failed to convert to hex.");
            break;
        }

        hex_index += 2;
    }

    hex_output[hex_index] = '\x0';
    return hex_output;
}

int comparePasswordAndHash(const char *password, const char *checkHexString) {
    const int passBlockLen =  8;
    char hashed[] = "\x20\x20\x20\x20\x20\x20\x20\x20";
    for (int index = 0; index < MIN(strlen(password), passBlockLen); ++index) {
        hashed[index] = password[index];
    }

    encrypt_string(hashed, "ENC_KEY_HERE_REMOVED", 1, passBlockLen);

    char *hexResult = stringToHexString(hashed);

    int result = strcmp(hexResult, checkHexString);
    free(hexResult);

    return result;
}
int main(void) {
    printf("Wait \n");
    sleep(3);
    printf("Start \n");

    const char *password = "1234";
    const char *checkHexString = "FA710A648892A940";

    if (comparePasswordAndHash(password, checkHexString) == 0) {
        printf("Yes!\n");
    } else {
        printf("No\n");
    }

    return 0;
}
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 12.08.2024, 18:06   #3
Willy53
Новичок
Джуниор
 
Регистрация: 12.08.2024
Сообщений: 2
По умолчанию

Цитата:
Сообщение от BDA Посмотреть сообщение
Предлагаю отказаться от replace_by_pos, чтобы постоянно не выделять и освобождать память, и работать в буфере hashed. По дороге еще пофиксил другие баги.
Спасибо, добрый человек! Счастья тебе, и квартальных премий побольше!
Willy53 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Утечка памяти [Освобождение памяти массива] denis76560 Общие вопросы Delphi 4 27.11.2016 18:20
Утечка памяти OmegaBerkut Общие вопросы Delphi 21 09.04.2015 22:12
Утечка памяти Vlad2891 Общие вопросы Delphi 11 27.02.2015 16:06
Ошибка при вызове free() ivan.tiran Общие вопросы C/C++ 5 04.12.2014 23:01
Утечка памяти Juffin Общие вопросы Delphi 3 02.11.2010 12:11