我有一些旧的代码,用于qsort对MFC CArray的结构进行排序,但我看到偶尔的崩溃可能会导致多个线程同时调用qsort.我使用的代码看起来像这样:
struct Foo
{
CString str;
time_t t;
Foo(LPCTSTR lpsz, time_t ti) : str(lpsz), t(ti)
{
}
};
class Sorter()
{
public:
static void DoSort();
static int __cdecl SortProc(const void* elem1, const void* elem2);
};
...
void Sorter::DoSort()
{
CArray<Foo*, Foo*> data;
for (int i = 0; i < 100; i++)
{
Foo* foo = new Foo("some string", 12345678);
data.Add(foo);
}
qsort(data.GetData(), data.GetCount(), sizeof(Foo*), SortProc);
...
}
int __cdecl SortProc(const void* elem1, const void* elem2)
{
Foo* foo1 = (Foo*)elem1;
Foo* foo2 = (Foo*)elem2;
// 0xC0000005: Access violation reading location blah here
return (int)(foo1->t - foo2->t);
}
...
Sorter::DoSort();
Run Code Online (Sandbox Code Playgroud)
我即将重构这个可怕的代码,std::sort但是想知道上面的内容是否真的不安全?
编辑:Sorter::DoSort实际上是一个静态函数,但本身不使用静态变量.
EDIT2:SortProc函数已更改为与实际代码匹配.
您的问题不一定与线程安全有关.
排序回调函数接收每个项目的指针,而不是项目本身.由于您正在排序Foo*您实际想要做的是访问参数Foo**,如下所示:
int __cdecl SortProc(const void* elem1, const void* elem2)
{
Foo* foo1 = *(Foo**)elem1;
Foo* foo2 = *(Foo**)elem2;
if(foo1->t < foo2->t) return -1;
else if (foo1->t > foo2->t) return 1;
else return 0;
}
Run Code Online (Sandbox Code Playgroud)