【问题标题】:Why quick sort throws an exception "write access violation"为什么快速排序会引发异常“写访问冲突”
【发布时间】:2020-12-09 21:28:22
【问题描述】:

我想编写快速排序,但我的程序出错了。首先在我的程序中,在 qsort 函数的主循环中有无限循环。然后我添加了left++; right--; 并且出现了异常。请检查我的代码并帮助我解决这个问题。

#include <iostream>

using namespace std;

typedef int (*CFT) (const void*, const void*);

struct User
{
    const char* name;
    int dept;
};

void print_id(User* v, int sz);
int cmp2(const void* a, const void* b);
void qsort(void* base, int n, size_t sz, CFT cmp);

User heads[] = {
    "g", 1,
    "d", 3,
    "s", 5,
    "c", 2,
    "t", 4,
    "h", 6,
    "y", 7,
    "z", 8,
};

int main() {
    const int SIZE = 8;
    print_id(heads, SIZE);
    qsort(heads, SIZE, sizeof(User), cmp2);
    cout << endl << endl;
    print_id(heads, SIZE);
    return 0;
}

void print_id(User* v, int sz) {
    for (int i = 0; i < sz; i++)
    {
        cout << v[i].name << "  " << v[i].dept << endl;
    }
}

int cmp2(const void* a, const void* b) {
    int aa = ((User*)a)->dept;
    int bb = ((User*)b)->dept;
    return aa > bb;
}

void qsort(void* base, int n, size_t sz, CFT cmp) {
    char* b = static_cast<char*> (base);
    char* lg = b;
    char* rg = b + n * sz;
    char* left = lg;
    char* right = rg;
    char* control = b + (n / 2) * sz;
    do
    {
        while (cmp(control, left) && left < rg) left += sz;
        while (cmp(right, control) && right > lg) right -= sz;
        if (left <= right) {
            for (int k = 0; k < sz; k++) {
                char tmp = left[k];
                left[k] = right[k];
                right[k] = tmp; // exception write access violation
            }
            left++;
            right--;
        }
    } while (left <= right);
    if (lg < right) qsort(lg, right - lg, sz, cmp);
    if (left < rg) qsort(left, rg - left, sz, cmp);
}

我现在不知道模板是如何工作的,所以请不要在答案中使用它们。

【问题讨论】:

  • 什么是User?请发minimal reproducible example
  • @cigien 我添加了结构声明
  • 请检查我的代码并帮助我解决这个问题。 -- How to implement classic sorting algorithms using modern C++
  • 提示:n:SIZE (8) 和 sz:sizeof (User),rg = b + n * sz; 将指向数组末尾的字节。使用right = rg;while (cmp(right, control),您可以访问数组末尾的内存。我想从这里开始可能会发生可怕的事情,我希望最终会发生,例如with // exception write access violation (您可以逐步调试以证明我是对还是错。)
  • @KamilCuk 为什么?我在其他种类和其他功能中使用了这种结构,例如示例。一切正常。

标签: c++ algorithm sorting quicksort


【解决方案1】:
qsort(heads, SIZE, sizeof(User), cmp2);
...
for (int k = 0; k < sz; k++)

sz 由 sizeof(User) 设置

sizeof(User) 与 head 数组中的用户数不同。 对于应该改为:

for (int k = 0; k < n; k++)

【讨论】:

  • 我知道。元素数量为 SIZE
  • 函数中的 sz 是一个元素的大小,n 是元素的数量
  • 我看到了 if (left sz 实际上是正确的。用法是交换2个项目。对此发表评论会有所帮助。
猜你喜欢
  • 1970-01-01
  • 2015-12-08
  • 2019-12-24
  • 2017-01-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-28
相关资源
最近更新 更多