提问人:Charles 提问时间:8/10/2023 更新时间:8/11/2023 访问量:149
在需要深度复制的结构上编码 std::sort
Coding std::sort on struct that needs deep copy
问:
我有一个结构体
typedef unsigned int gsk_uint32;
typedef struct _gsk_oid {
int count;
gsk_uint32 * elements;
} gsk_oid;
struct oidX : public gsk_oid
{
oidX(); // Default
oidX(int countX, gsk_uint32 first, ...); // From list of integers
oidX(const char* oidString); // From dotted notation
oidX(const gsk_oid *inOID); // From gsk_oid
~oidX(); // destructor
};
我有一个结构,上面有 OidX 作为成员:
struct oidPair {
oidX *TheOID;
const char *Descript;
oidPair(oidX *inputOID, const char *inputDescript);
~oidPair();
};
我定义了上述结构的数组
oidPair testOIDs[4] = {
oidPair(new oidX("2.23.140.1.2.3"), "Certificates issued in accordance with the CA/Browser Forum's Baseline Requirements - Individual identity asserted"),
oidPair(new oidX("2.23.140.1.1"), "Extended Validation (EV) guidelines certificate policy"),
oidPair(new oidX("1.3.6.1.4.1.4146.1.20"), "Organization validation certificate policy"),
oidPair(new oidX("2.23.140.1.2.2"), "Certificates issued in accordance with the CA/Browser Forum's Baseline Requirements - Organization identity asserted") };
是的,我可以按排序顺序定义它们,但元素比我上面列出的要多得多,我想避免粗心大意的陷阱,所以在启动时我想对上面的数组进行排序。我发行std::sort(testOIDs, testOIDs+4, &Oid_less);
下面是比较函数:
int DecodeOID::Oid_cmp(const gsk_oid *left, const gsk_oid *right)
{
int cnt = std::min(left->count, right->count); // Shorter of the two vectors
int ret = memcmp(left->elements, right->elements, cnt*4); // compare elements
if ( 0 != ret ) return ret; // if unequal we are done
return left->count - right->count; // else longer is considered greater
}
bool DecodeOID::Oid_less(const oidPair &left, const oidPair &right)
{
const gsk_oid *l = left.TheOID;
const gsk_oid *r = right.TheOID;
int ret = Oid_cmp(l, r);
return ret < 0;
}
排序第三次调用 Oid_less &right,引用具有未初始化 OidX 的 oidPair,并且因内存异常而失败。我知道我可能需要一个移动运算符或类似的东西,但我不知道到底要编码什么。建议表示赞赏。
答:
0赞
Charles
8/11/2023
#1
谢谢大家。是的,向 oidPair 添加副本和 operator=() (基于 swap)解决了这个问题。我专注于发生异常的 OidX,但当然是正在排序的 oidPair。
开销不是一个主要问题。此时,该表有 22 个项目,可能不会超过两倍。它几乎以正确的顺序开始,因此交换的次数很少。
friend void swap(oidPair& first, oidPair& second) // nothrow
{
using std::swap;
swap(first.TheOID, second.TheOID);
swap(first.Descript, second.Descript);
}
oidPair& operator=(oidPair other)
{
swap(*this, other);
return *this;
}
oidPair(const oidPair &key) // System copy
{
this->TheOID = new oidX(key.TheOID);
this->Descript = key.Descript;
}
评论
std::unique_ptr
std::shared_ptr
oidX(int countX, gsk_uint32 first, ...);
oidPair
struct