【问题标题】:Quick Sort Algorithm: Thread 1 EXC Bad Access (code=2)快速排序算法:线程 1 EXC 错误访问(代码=2)
【发布时间】:2020-04-27 16:53:19
【问题描述】:

我的快速排序算法有问题。当“cout”语句未注释或调试时,它似乎可以正确运行,但除此之外,它通常(但不总是)给我一个“线程 1:EXC_BAD_ACCESS(代码=2,地址=0x7ffeef3ffff8)”错误。有谁知道如何解决这一问题?起初我以为是随机数生成器,但即使在我对分区枢轴进行去随机化后,它仍然继续发生。

代码的主要部分是名为“Partition”和“Q_Sort”的两个函数。 “Switch”只是交换分区内的元素位置,“Rand”生成一个随机整数,“Disp”只是显示向量。 谢谢。

#include <iostream>
#include <vector>
#include <algorithm>
#include <iomanip>
#include <array>
#include <time.h>
#include <cstdlib>

using namespace std;

//Display vector
void Disp(vector<double> vect){
    if (vect.size() == 1){
        cout << "{" << vect[0] << "}" <<endl;
    }
    else if(vect.size() < 1){
        cout << "{" << "}" <<endl;
    }
    else{

        for (int ii = 0; ii < vect.size(); ii++) {
            if (ii == 0) {
                cout << "{" << vect[ii] << ", " << flush;
                continue;
            }
            if (ii == vect.size() - 1) {
                cout << vect[ii] << "}" << endl;
                continue;
            }
            cout << vect[ii] << ", " << flush;
        }
    }

}
//Random integer
int Rand(int range){
    srand((unsigned) time(0));
    int r = rand() % range;
    return r;
}

//Switch
void Switch(vector<double> &vect,int switcher ,int switchee){
    if(switchee != switcher){
        int old = vect[switchee];
        vect[switchee] = vect[switcher];
        vect[switcher] = old;
    }
}

//Partition
tuple<int,int,int,int> partition(vector<double> &vect, int around, int start, int end){
//    cout<<"Around: " <<around<<endl;

    double num = vect[around];
    Switch(vect,around,start);
    int i = start;
    int j = start + 1;
    int m = start;
    int mj = start;
    while(j < end){
//        cout<<endl;
        if(vect[j] >= num){
            if(vect[j] == num){
                Switch(vect, mj + 1, j);
                mj +=1;
            }
            j += 1;
            continue;
        }
        else if(vect[j] < num){
            Switch(vect,mj + 1, j);
            Switch(vect,m,mj + 1);
            mj += 1;
            m += 1;
            j += 1;
        }
    }
//    cout<<"End update : "<<endl;

    return {m,mj,j - 1,i};
}


void Q_sort(vector<double> &vect,int around, int start, int end){


    auto [mm, mmjj, jj, ii] = partition(vect,around, start, end);
//    cout<<"Left "<<endl;
    // LEFT

    int startL = ii; // startL = 0;
    int endL = mm ;
//    cout<<endl<< "New vector "<<endl;

//    Disp(vect);
//    cout<<"end "<< endL<<endl;
//    cout<<"start "<< startL<<endl;
    if(endL - startL > 0){

        int r = Rand(endL - startL) + startL;

        Q_sort(vect, r,startL,endL);
    }

    //RIGHT
    int startR = mmjj; //+ 1;
    int endR = jj;
//    cout<<"Right "<<endl;
//    cout<<endl<< "New vector "<<endl;
//    Disp(vect);
//    cout<<"end "<< endR<<endl;
//    cout<<"start "<< startR<<endl;
//    
    if (endR - startR> 1){
        int r = Rand(endR - startR) + startR;
        Q_sort(vect,r,startR,endR + 1);
    }
}


int main(int argc, const char * argv[]) {
    vector<double> x{1,5,3,5,4,7,2,14,7,14,4};
    Q_sort(x, 0, 0, x.size());

    Disp(x);
    std::cout << "Hello, World!\n";
    return 0;
}

【问题讨论】:

  • 你用的是什么调试器?

标签: c++ c++17


【解决方案1】:

尝试运行此代码:

给我的是worked。 (可能是播种机造成了问题。)

使用-std=c++1z 或更高版本编译它。 (PS:对不起,我忘了注意 C++17 标签,你可能只会这样做)。

#include <algorithm>
#include <array>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <time.h>
#include <vector>

using namespace std;

// Display vector
void Disp(vector<double> &v) {
    cout << "{";
    for (size_t i = 0; i < v.size(); ++i) {
        if (i == v.size() - 1)
            cout << v[i];
        else
            cout << v[i] << ", ";
    }
    cout << "}" << endl;
}

// Random integer
int Rand(int range) {
    return (rand() % range);
}

// Switch
void Switch(vector<double> &v, int x, int y) {
    if (x != y)
        swap(v[x], v[y]);
}

// Partition
tuple<int, int, int, int> partition(vector<double> &v, int around, int start, int end) {
    auto num = v[around];
    Switch(v, around, start);
    int i, j, m, mj;
    i = j = m = mj = start;
    while (++j < end) {
        if (v[j] >= num) {
            if (v[j] == num)
                Switch(v, ++mj, j);
            continue;
        } else if (v[j] < num) {
            Switch(v, ++mj, j);
            Switch(v, m++, mj);
        }
    }
    return {i, m, mj, --j};
}

// Quick sort
void Q_sort(vector<double> &v, int around = 0, int start = 0, int end = -1) {
    if (end == -1) end = v.size();
    auto [startL, endL, startR, endR] = partition(v, around, start, end);
    if (endL - startL > 0) {
        int r = Rand(endL - startL) + startL;
        Q_sort(v, r, startL, endL);
    }
    if (endR - startR > 1) {
        int r = Rand(endR - startR) + startR;
        Q_sort(v, r, startR, endR + 1);
    }
}

// Driver function
int main() {
    srand(time(NULL)); // seeder should be called only once during execution
    vector<double> x = {1, 5, 3, 5, 4, 7, 2, 14, 7, 14, 4};
    Q_sort(x);
    Disp(x);
    return 0;
}

【讨论】:

  • 这行得通。谢谢你。在我的中,我注释掉了播种机,它工作得很好。你知道为什么会这样吗?早些时候,我删除了对随机整数的调用作为故障排除措施,它仍然发生。还有,为什么当播种机在 Rand 函数而不是 main 中时,cout 语句和调试器会影响它是否正确运行?
  • @RahelMiz 这只是您的代码正常工作的巧合。当我第一次运行它时它工作了!后来抛出分段错误。这主要是因为访问超出范围的值。但我还不能弄清楚原因(我知道为什么会发生,但不知道发生在哪里)。您的代码中可能仍然存在一些意想不到的东西。我刚刚用不同的向量运行了修改后的代码大约 35 次,发现它可以工作,所以我将其发布为答案。一旦我找出原因,我会更新它。
  • 看到相同的代码像魅力一样工作。运行 2-3 次,你会得到核心转储。 wandbox.org/permlink/D2VCaiQ1j4yciGAT 。这种同时发生是因为每次每个变量在不同的地方占用内存。有时您正在访问的索引位于空闲区域,而其他时候它会弄乱其他变量的内存并因此出错。
  • @RahelMiz 我尝试使用vector::at而不是operator [],希望它在访问时会抛出超出范围的异常,但即使这样也没有抛出任何异常,简单的程序导致分段错误。可能某个地方出了问题。最好你自己弄清楚,或者尝试清理算法并分析极端情况。
猜你喜欢
  • 1970-01-01
  • 2021-09-21
  • 1970-01-01
  • 2017-01-14
  • 1970-01-01
  • 2021-09-17
  • 2017-11-04
  • 1970-01-01
  • 2011-08-07
相关资源
最近更新 更多