Есть ли способ исправить ошибку сегментации? я не могу понять это

Я не уверен, почему я получаю ошибку сегментации в своем коде?

 class Node {
    public:
        int data;
        Node *next;
};

void push_back(Node** head_ref, int new_data) {  
    Node* new_node = new Node(); 
  
    Node *last = *head_ref;
    new_node->data = new_data;  
    new_node->next = NULL;  

    if (*head_ref == NULL) {  
        *head_ref = new_node;  
        return;  
    }  
  
    while (last->next != NULL)  
        last = last->next;  
  
    last->next = new_node;
    
    return;  
}  

int getHash(string initials) {
    string digits;
    
    for (int i = 0; i < 3; i++) {
        switch(initials[i]) {
            case 'A':
            case 'B':
            case 'C':
                digits += "2";
                break;
            case 'D':
            case 'E':
            case 'F':
                digits += "3";
                break;
            case 'G':
            case 'H':
            case 'I':
                digits += "4";
                break;
            case 'J':
            case 'K':
            case 'L':
                digits += "5";
                break;
            case 'M':
            case 'N':
            case 'O':
                digits += "6";
                break;
            case 'P':
            case 'Q':
            case 'R':
            case 'S':
                digits += "7";
                break;
            case 'T':
            case 'U':
            case 'V':
                digits += "8";
                break;
            case 'W':
            case 'X':
            case 'Y':
            case 'Z':
                digits += "9";
                break;
        }
    }
    
    return stoi(digits);
}

int getSize (Node* head) {
    int size = 0;
    bool not_null = true;
    Node *current = head;
    
    while (not_null) {
        if (current->next == NULL) {
            not_null = false;
            return size;
        } else {
            size++;
            current = current->next;
        }
    }
}

int main() {
    int count = 512;
    string initials;
    map<int, int> stats;
    Node* bitvec[count];
    for ( int i = 0; i < count; i++ ) {
        Node *data_node = new Node;
        data_node->data = 1;
        bitvec[i] = data_node;
    }

    for ( int i = 0; i < count; i++ ) {
        for (int j = 0; j < 3; j++) 
            initials.push_back((char)(rand() % 26 + 65));
        
        int hash = getHash(initials);
        
        cout << initials << " - " << hash << " - " << hash % count << endl;
        //cout <<"-"<< count<< endl;
        push_back(&(bitvec[hash % count]), 0);
        
        initials = "";
    }

    cout << "collision array" << endl;

    for ( int i = 0; i < count; i++ ) {
            if ( stats.count( getSize(bitvec[i]) ) <= 0 ) {
                    stats[ getSize(bitvec[i]) ] = 1;
            } else {
                    stats[ getSize(bitvec[i]) ]++;
            }
            cout << setw( 2 ) << getSize(bitvec[i]) << " ";
            if ( ( i + 1 ) % 25 == 0 ) {
                    cout << endl;
            }
    }

    int total = 0;
    cout << endl;
    for ( map<int, int>::iterator it = stats.begin( ); it != stats.end( ); it++ ) {
            if ( it->first != 0 ) {
                    total += it->second;
            }
            cout << it->first << " collisions occurred #" << it->second << endl;
    }

    cout << "Max number of collisions is: " << ( --stats.end( ) )->first << endl;
    cout << "Total collisions: " << total << endl;
    float avg = (float) count / total;
    cout << "average search: " << avg << endl;
  
    return 0;
}

person nugget    schedule 20.12.2020    source источник
comment
У вас есть небольшая дыра в getSize. Введите его с нулевым head, и он пойдет бум.   -  person user4581301    schedule 20.12.2020
comment
Повторение вышесказанного, вроде. while (last->next != NULL) трудно понять правильно. Обычно лучше переписать для while (last != NULL), чтобы не беспокоиться о попытке last->next, когда last равно нулю. Пять баксов говорят, что один будет твоей ошибкой.   -  person user4581301    schedule 20.12.2020
comment
Примечание: есть изящный трюк, который вы можете сделать с указателем на указатель, чтобы сделать вставки и удаление из односвязного списка очень просто.   -  person user4581301    schedule 20.12.2020
comment
Обходить ограничение на количество кода, которое вы можете публиковать без пояснительного текста, просто повторяя свой текст, — это не способ использования этого сайта. Причина ограничения заключается в том, чтобы побудить вас предоставить подробное объяснение вашей проблемы. Пробовали использовать отладчик? Что должен делать ваш код? Где происходит сбой? Предоставьте минимальный воспроизводимый пример   -  person Alan Birtles    schedule 20.12.2020
comment
Примечание: если вам не нужно создавать собственный связанный список, не делайте этого. В C++ есть все виды подходящих контейнеров, которые сделают все, если вам нужна работа с никакой суеты и никакой суеты.   -  person user4581301    schedule 20.12.2020


Ответы (1)


In main

for ( int i = 0; i < count; i++ ) {
    Node *data_node = new Node;
    data_node->data = 1;
    // whoops! Didn't set data_node->next = NULL.
    bitvec[i] = data_node;
}

Эта ошибка означает, что while (last->next != NULL) и подобные тесты позже в коде терпят неудачу. Это означает, что мой комментарий под вопросом указал на местонахождение ошибки, но неправильно указал причину. Такова жизнь. Должен был принять меня на пари.

Это можно упростить до

for ( int i = 0; i < count; i++ ) {
    bitvec[i] = new Node{1, NULL};
}

Который использует объединенную инициализацию, чтобы убедиться, что все инициализировано.

Это предотвращает сбой программы. Я не проверял правильность вывода.

person user4581301    schedule 20.12.2020