简体   繁体   English

为什么此代码会导致程序崩溃?

[英]Why does this code cause the program to crash?

void gameListType::sortAscending() {

    nodeType<gameType> *current;
    nodeType<gameType> *next;
    nodeType<gameType> *prev;
    nodeType<gameType> *temp;

    temp = first;
    prev = first;
    current = first;
    next = current->link;

    while ( current->link !=NULL){
        if (current ==first){
             if (current->info.getPrice() > next->info.getPrice()){
            temp->info = current -> info;
            temp->link = next ->link;
            next -> link = temp;
            current = temp;
            delete temp;
            }
        }
        else if (current !=first ){
            if (current->info.getPrice() > next->info.getPrice()){
                temp->info = current->info;
                temp-> link = next ->link;
                next->link = temp;
                prev->link = next;
                current = temp;
                delete temp;
            }
        }
        if(current == first){
            prev = first;
        }
        else{
            prev = prev->link;
        }
        current = current ->link;
        next = next->link;
    }
}

running this code will cause my program to crash, any ideas? 运行此代码将导致我的程序崩溃,有什么想法吗? This is basically to sort the items in a CUSTOM linked list. 这基本上是对CUSTOM链接列表中的项目进行排序。 It apparently only crashes after the loop has completed once, so the second loop is the problem as to why it is crashing. 显然,它仅在循环完成一次后才崩溃,因此第二个循环是为什么崩溃的问题。

Your code crashes because you treat temp variable as if it was pointing to a temporary object, but it actually points to one of the objects in the list you're sorting. 代码崩溃是因为您将temp变量视为指向临时对象,但实际上它指向要排序的列表中的对象之一。

Take this simple path: 选择以下简单路径:

temp = first;
prev = first;
current = first; // temp == first and current == first, so temp == current
next = current->link;

while ( current->link !=NULL){          // true
    if (current ==first){               // true
        if (current->info.getValue() > next->info.getValue()){ // true
            temp->info = current->info; // temp == current, so nothing changes
            temp->link = next->link;    // temp == current, so current->link = next->link
            next -> link = temp;        // temp == current, so next->link = current
            current = temp;             // temp == current, so nothing changes
            delete temp;                // temp == current, so delete both temp and current
        }
    }
// ...
    current = current ->link;         // but we deleted current! segfault

Exactly the same problem is present in the else if block (there's a bit of code duplication in your sample). else if块中确实存在相同的问题(示例中有一些代码重复)。 The problem is eliminated by creating a new temporary object for the temp variable. 通过为temp变量创建一个新的临时对象,可以消除此问题。 Note that it's enough to have a temporary for info alone: 请注意,仅拥有一个临时的info就足够了:

if (current->info.getValue() > next->info.getValue()){
    // No need to mess with pointers here, current and next are advanced later
    // Bonus points for using a swap function instead
    InfoClass temp = current->info;
    current->info = next->info;
    next->info = temp;
}

This approach doesn't modify next and current pointers, thus fixing another problem in your function (ie next->link pointing to current instead of current->link pointing to next ). 这种方法不会修改nextcurrent指针,从而解决了函数中的另一个问题(即next->link指向current而不是current->link指向next )。


I want to address one other point here, which is that even when fixed, your function doesn't actually perform a sort; 我想在这里解决另一点,那就是即使固定,您的函数实际上也不会执行排序。 it only performs a single pass of bubble sort which 'pushes' the biggest value in the list to the right position (that is: the end of the list). 它只执行一次冒泡排序 ,将列表中的最大值“推”到正确的位置(即:列表的末尾)。 Even when implemented correctly, bubble sort is an inefficient algorithm with a quadratic complexity in the average case. 即使正确实施,冒泡排序也是一种效率低下的算法,平均情况下具有二次复杂度。

Merge sort is a common algorithm used to sort lists. 合并排序是用于对列表进行排序的常用算法。 Alternatively, depending on what you're sorting, it might be beneficial to simply copy data into a vector, sort it with std::sort and reconstruct the list from the sorted data (this approach is simplest to implement and least error-prone, though merge sort is always fun to write). 另外,根据您要排序的内容,将数据简单地复制到向量中,使用std::sort对其进行std::sort并从排序后的数据中重建列表可能会有所帮助(这种方法最容易实现,而且出错率最低,虽然合并排序总是很有趣)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM