Утечки памяти в C ++ при построении классов - PullRequest
1 голос
/ 04 июня 2019

Я пишу на C ++, пытаюсь реализовать хеш-таблицу с использованием массивов.

Функция хеширования взята из this Пост переполнения стека.

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

  • Вставить элемент с помощью % table's total size.
  • Когда # of elements inserted (= current size) >= table's total size,
  • создатьnew table с удвоенным размером и заново вставьте все элементы.

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

Обратите внимание, что таблица создается только для неотрицательных целочисленных значений.

Я не могу пройти мимо построения таблицы: постепенно увеличивается использование памяти, а также процессоров.

Это должно означать, что есть проблема, связанная с проверкой условия, когда нужно увеличивать размер таблицы.

Конструктор и деструктор таблицы:

// I'm defining these here because they depend on the integer's bit size.
#define INVERSE 0x119de1f3
#define HASHER  0x45d9f3b


HashTable::HashTable(size_t initial_size, uint32_t *initial_data)
{
    total_size = 4U * initial_size;
    current_size = initial_size;

    data = new table[total_size];

    build(initial_data);
}

HashTable::~HashTable()
{
    delete[] data;

    total_size = 0U;
    current_size = 0U;
}

Чтобы построить, мы хэшируем и помещаем (вставляем)каждый начальный элемент втаблица:

void HashTable::build(uint32_t *initial_data)
{
    for (size_t i = 0U; i < current_size; i += 1U)
    {
        insert(initial_data[i]);
    }
}

Для вставки мы также используем хеш-функцию:

void HashTable::insert(uint32_t num)
{
    uint32_t index = hash(num);

    try
    {
        data[index].num = num;
        data[index].exists = true;

        current_size += 1U;
    }
    catch (out_of_range& error)
    {
        ;   // TODO stuff after writing main.
    }
}
uint32_t HashTable::hash(uint32_t num)
{
    if (current_size >= total_size / 2U) {
        doubleTable();

        for (size_t i = 0U; i < current_size; i += 1U)
        {
            insert(data[i].num);
        }
    }

    num = ((num >> 16) ^ num) * HASHER;
    num = ((num >> 16) ^ num) * HASHER;
    num =  (num >> 16) ^ num;

    return (num % total_size);
}

Наконец, вот фиктивная основная функция:

int main(void)
{
    uint32_t initial_data[3] = {1, 3, 5};

    HashTable h(3U, initial_data);
    return 0;
}

Вот как структурирована таблица:

struct table
{
    uint32_t num;
    bool exists = false;
};

И соответствующие определения:

class HashTable
{
    private:
        table *data;

        size_t total_size;
        size_t current_size;

        uint32_t hash(uint32_t num);
        uint32_t unhash(uint32_t num);

        void build(uint32_t *initial_data);

        void doubleTable(void);

    public:
        HashTable(size_t initial_size, uint32_t *initial_data);
        ~HashTable();

        void insert(uint32_t num);

После компиляции с -ggdb3 и запуска valgrind я получаю приставание uninitialized value of size 8ошибка.

Вот некоторые журналы valgrind:

--1632-- Valgrind options:
--1632--    --leak-check=full
--1632--    --show-leak-kinds=all
--1632--    --track-origins=yes
--1632--    --verbose
--1632--    --log-file=valgrind-out.txt
==1632== Use of uninitialised value of size 8
==1632==    at 0x1093E8: HashTable::insert(unsigned int) (in /home/xlxs4/Git/CCDT/src/structures/hashtable/a.out)
==1632==    by 0x1095DC: HashTable::hash(unsigned int) (in /home/xlxs4/Git/CCDT/src/structures/hashtable/a.out)
==1632==    by 0x1093BD: HashTable::insert(unsigned int) (in /home/xlxs4/Git/CCDT/src/structures/hashtable/a.out)
==1632==    by 0x1096B0: HashTable::build(unsigned int*) (in /home/xlxs4/Git/CCDT/src/structures/hashtable/a.out)
==1632==    by 0x10933C: HashTable::HashTable(unsigned long, unsigned int*) (in /home/xlxs4/Git/CCDT/src/structures/hashtable/a.out)
==1632==    by 0x10920A: main (main.cpp:15)
==1632==  Uninitialised value was created by a heap allocation
==1632==    at 0x483950F: operator new[](unsigned long) (vg_replace_malloc.c:423)
==1632==    by 0x1092F7: HashTable::HashTable(unsigned long, unsigned int*) (in /home/xlxs4/Git/CCDT/src/structures/hashtable/a.out)
==1632==    by 0x10920A: main (main.cpp:15)

Я уже прошел этот пост на , исключая неопределенные значения , этот ТАК пост о неинициализированное значение размера 8 .

Чего мне не хватает?

Дайте мне знать, если вам нужны какие-либо дополнительные классификации, или вы хотите, чтобы я более подробно объяснил свой мыслительный процесс

Заранее спасибо:)

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