为什么这段代码导致程序崩溃?

时间:2014-08-12 10:55:21

标签: c++ crash iterator

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;
    }
}

运行此代码会导致我的程序崩溃,任何想法?这基本上是对CUSTOM链接列表中的项目进行排序。它显然只在循环完成一次后崩溃,所以第二个循环是它崩溃的原因。

1 个答案:

答案 0 :(得分:1)

您的代码崩溃是因为您将temp变量视为指向临时对象,但它实际上指向您要排序的列表中的一个对象。

走这条简单的道路:

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

else if块中存在完全相同的问题(样本中有一些代码重复)。通过为temp变量创建新的临时对象可以消除该问题。请注意,仅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;
}

此方法不会修改nextcurrent指针,从而修复了函数中的另一个问题(即next->link指向current而不是{{1}指向current->link)。


我想在这里解决另一个问题,即使修复后,你的功能实际上并没有进行排序;它只会执行bubble sort的单次传递,而这只会推送&#39;列表中的最大值到正确的位置(即:列表的末尾)。即使正确实施,冒泡排序也是一种效率低下的算法,在一般情况下具有二次复杂度。

Merge sort是用于对列表进行排序的常用算法。或者,根据您要排序的内容,简单地将数据复制到向量中,使用next对其进行排序并从已排序的数据重建列表(这种方法最简单的实现和最少的错误)可能是有益的。 -prone,虽然合并排序总是有趣的写。)