Почему я получаю ошибку сегментации здесь? - PullRequest
1 голос
/ 21 апреля 2020
void LinkedList<T>::mergeSort(Node*& curr) {
    if (curr->next != nullptr) { //Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeef3ffff8)
        Node *ptr1 = nullptr;
        Node *ptr2 = curr;
        //splits linked list
        for (int i = 0; i < getLength() / 2; i++) {
            ptr1 = ptr2;
            ptr2 = ptr2->next;
        }
        ptr1->next = nullptr;
        ptr1 = curr;
        //recursive call for sorting
        mergeSort(ptr1); //Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeef3ffff8)
        mergeSort(ptr2);
        //merge lists back together
        if (ptr1 == nullptr)
            curr = ptr2
        else if (ptr2 == nullptr)
            curr = ptr1

        Node *reff = ptr1;

        while (reff->next != nullptr) {
            reff = reff->next;
        }
        reff->next = ptr2;
        curr = reff;
    }
}

Кажется, все работает, ожидайте эту функцию. Я всегда получаю ошибку сегментации, и я не понимаю, почему это происходит.

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

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

Так что это дает мне эту ошибку: Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeef3ffff8). Как я могу выяснить, что означает ошибка под кодом = 2 и другими числами?

Ответы [ 2 ]

3 голосов
/ 21 апреля 2020

Есть проб. многочисленные вещи не так. Это показывает, как это можно сделать с помощью std::list. Я не знаю, был ли задан API, но давайте сделаем его отдельной функцией, которая принимает список.

template<typename T>
void mergesort( std::list<T>& list ){

Работать можно только в том случае, если у нас более одного элемента

    auto const size = list.size();
    if( size > 1) {

Затем список делится на два списка.

        auto mid = list.begin();
        std::advance( mid, size/2 );        
        std::list<T> other;        
        other.splice( other.begin(), list, list.begin(), mid );

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

    mergesort( list );
    mergesort( other );

Затем необходимо объединить частичные результаты.

    list.merge( other );        

И мы закончили. Смотри рабочую версию здесь

1 голос
/ 21 апреля 2020
for(int i=0;i<getLength()/2;i++)

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

Итак, getLength() является функцией-членом LinkedList. Когда мы делаем рекурсивные вызовы, он всегда сообщает нам о сохраненных length всех LinkedList. Но это не то, что мы хотим - мы хотим, чтобы число узлов в цепочке Node s, которые мы передали. Вместо этого, когда мы в первый раз делаем рекурсивный вызов, мы пытаемся разделить его на то же количество узлов, что и оно. уже имеет (в первой половине, и ноль узлов во второй половине). Поскольку в этом нет никакого прогресса, мы в конечном итоге взорвем стек рекурсивными вызовами.

...