gpt4 book ai didi

c++ - 如何判断 std::vector 是否调整了自身大小,以及如何解释指向 vector 内值的指针不再有效?

转载 作者:行者123 更新时间:2023-11-30 03:33:22 25 4
gpt4 key购买 nike

我知道如果调整 std::vector 的大小(我相信只是大小增加了),则 vector 的内存位置将重新定位,以便在堆内存中找到一个真正适合新位置的新位置尺寸。在那种情况下,如果我的指针 A、B 和 C 之前指向 vector 中的元素,它们将指向旧的、已取消分配的内存位置,并且不再有效。

我想知道是否 A:如果发生此类事件时是否有可能收到通知,而无需我明确管理何时调整 std::vector 的大小时,以及 B:如何处理不再引用在内存中的正确位置。

B 部分有点含糊,所以我将缩小我想要使用此行为的用例范围。在我的情况下,我有一个类维护一个对象 vector ,这些对象内部有多个指针,如下所示:

class MultiPointer{
public:
Type1* t1;
Type2* t2;
Type3* t3;
MultiPointer(Type1*t1, Type2*t2, Type3*t3);
};
...
// attempt to create singleton pattern to make pool of each object type for each class
class Type1{
...
static vector<Type1> arr1 = ...
}
class Type2{
...
static vector<Type2> arr2 = ...
}
class Type3{
...
static vector<Type3> arr3 = ...
}
...

//note, would actually use CRTP to make sure I don't have to type out static vector<TypeN> each time

MultiPointer a(&arr1[0], arr2[0], arr3[0]);
MultiPointer b(&arr1[1], arr2[1], arr3[1]);
MultiPointer c(&arr1[2], arr2[2], arr3[2]);
std::vector<MultiPointer> mpv= {a,b,c};
... insertions into arr1,2,3 ...
//How do I make sure that a, b, and c still point to the same types?

请注意,在我的情况下,我可以在所有相关的时间访问 arr1->3,因为它是一个静态变量,而且我知道我正在使用的类型。

我的想法是将 arr1 的指针值复制到一个单独的变量中,即

Type1* arr1ptrcpy = &(Type1::arr1[0]);

然后我会在需要的时候检查大小是否改变了,如果大小改变了我会检查指针是否相同(或者只检查指针是否相同)

//ie in main
if(arr1ptrcpy != &(Type1::arr1[0])){
// for each multi pointer in mpv, adjust pointers for arr1.
...
}

如果我注意到地址发生变化,我会进行指针算术运算以找到旧指针相对于新地址的正确位置。

// in MultiPointer
...
// if pointers don't match for arr1
t1 = (arr1ptrcpy - t1) + Type1::arr1[0];
...
// if pointers don't match for arr2
t2 = (arr2ptrcpy - t2) + Type2::arr2[0];
...
// if pointers don't match for arr3
t2 = (arr3ptrcpy - t3) + Type3::arr3[0];

虽然我可以使用句柄来完成这一切,但这需要运行时开销来取消引用指针,因为我会有很多指针。在这种情况下,与取消引用指针相比,我检查 vector 更改的频率要低得多。如果这可以用迭代器完成,每个迭代器没有额外的内存开销,我也愿意看看如何完成。

编辑:我想提供更多关于我的实际应用程序试图完成什么/它是如何构建的信息。在实际用例中,有多种类型的 MultiPointer,其中一些引用相同的对象,但指针类型不同(因此首先需要指针)并且它们引用的对象在上下文之外的其他地方使用多指针也是如此。

在我的实际应用程序中,“MultiPointer”充当一组对象,这些对象具有附加到这些分组的不同功能。例如,您可能有一个具有 Position* 和 Velocity* 的 PhysicsMultiPointer,以及一个具有 DisplayImage* 和 Position* 的 GraphicMultiPointer。它们都将指向同一个 Position 对象。

第二次编辑:

我应该提到我需要类型 vector 中的所有元素都在连续的内存中,如果不是这种情况,我什至不会为这整个考验而烦恼,因为我只会有指向堆对象的指针,而堆对象不会换地点。

最佳答案

A: If it was possible to be notified when such an event happens, with out me explicitly managing when a std::vector is resized,

没有。

您可以很容易地判断它何时将要发生,但您无法在事后判断它何时发生。 vector 重新分配只会在您执行某些操作使 vector 的大小超过其当前的容量 时发生(或者您调用 shr​​ink_to_fit)。因此,如果您将 4 个项目插入 vector,如果 capacity - size 为 4 或更多,它不会重新分配自身。

现在,你可以使用这个事实来为插入函数构建包装函数/对象,它将检查插入前后的容量并返回它是否发生了变化(如果发生重新分配,则必须增加容量)。

但是,处理此问题的更好方法是简单地……不要让它发生。使用 reserve 函数使容量足够大,您根本不需要重新分配。通过这样做,您将不必关心重置指针等。

请注意,以上仅涵盖由于重新分配而导致的指针失效。如果将对象插入 vector 的中间,指针和引用将失效,但只有那些指向插入点处的元素和所有后续元素的指针/引用。

B: how to deal with the pointers no longer referencing the correct location in memory.

不要使用指针。相反,使用索引。除非你插入到 vector 的中间;索引对此无能为力。

如果索引对您不起作用,那么我会强烈重新考虑使用 vector。如果您非常需要元素的稳定性,那么 listforward_list 似乎是更适合这项工作的工具。或者,如果您有权访问 Boost,boost::stable_vector

关于c++ - 如何判断 std::vector 是否调整了自身大小,以及如何解释指向 vector 内值的指针不再有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43012451/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com