vector内部类的成员函数,在vector reallocation时活跃

问题描述 投票:0回答:0

编辑:解决方案

这个问题可能涉及一个严重的 UB。我正在寻找一个解释并解决这个问题。

最后我和我的团队遇到了一个奇怪的(但可以解释的)问题,我们在网上找不到任何类似的问题,我们想要一些答案。

  1. 我们了解向量的重新分配问题(大小变化)。然而,我们无法理解为什么“this”指针不会在发生此更改时自动更新。
  2. 有没有办法将“this”指针更新为正确的地址?
  3. 解决以下问题的最佳和最通用的方法是什么(我们的建议可以在本文末尾找到,但我们正在寻找更优雅/通用的方法)?

案例:

我们有一个类 [TesrClass] 和这个类的向量容器。 TestClass 函数之一,导致向量容器重新分配(在推送/放置期间),并在之后继续使用类成员变量/函数 [UB?] 的一些后续步骤。

问题:

重新分配后,“this”对象在这个成员函数[Haleluja]中不再有效。这是预期的行为吗? [使用 g++ & clang - Ubuntu 16.04 测试]。

代码演示:

#include <iostream>
#include <vector>
#include <memory>

using namespace std;

class TestContainer;
class TestClass {
public:
    TestClass(int n, TestContainer *tcontainer) {
        num = n;
        container = tcontainer;
    }

    void func();

private:
    int num;
    TestContainer *container;
    void class_member_function();

};

class TestContainer {
public:
    vector<TestClass> tc_vec;
};

void TestClass::class_member_function() {
    cout << "Class Member Function:" << endl << endl;
    cout << "Container Vector Data:" << endl;
    for (auto& elem : container->tc_vec) {
        cout << "Object Address: " << &elem << " | Number: " << elem.num << endl;
    }
    cout << endl;
    cout << "Function Data:" << endl;
    cout << "Object Address: " << this << " | Number: " << num << endl;
    cout << "=====================" << endl;
}

void TestClass::func() {
    class_member_function();
    /*
     * Example Print:
     * =============================================
     * Class Member Function:

     * Container Vector Data:
     * Object Address: 0x22fcc20 | Number: 10

     * Function Data:
     * Object Address: 0x22fcc20 | Number: 10 // As expected.
     * =============================================
     */
    container->tc_vec.emplace_back(4, container);
    class_member_function();
    /*
     * Example Print:
     * =============================================
     * Class Member Function:

     * Container Vector Data:
     * Object Address: 0x22fd050 | Number: 10 // Address changed as expected, as a result of the vector's reallocation (reserve will solve this problem, but not a generic solution).
     * Object Address: 0x22fd060 | Number: 4

     * Function Data:
     * Object Address: 0x22fcc20 | Number: 0 // Pay attention!! Address didn't change, and doesn't exists in the vector anymore.
     * =============================================
     */
}

int main() {
    TestContainer container;
    container.tc_vec.emplace_back(10, &container);
    container.tc_vec[0].func();
    return 0;
}

我们的建议:

1. 使用储备并检查容量(由于一般原因和更智能的资源管理,我们正试图避免这种方式)。 2. 在向量内部使用智能指针(```vector>```)。 3.不使用直接访问类成员,而是将类ID属性[在上面的例子中不存在]保存在函数本地(更改前),然后每次在容器向量中搜索它以访问正确的放在内存中 [Still UB?]。 4. 使用```std::list``` 代替```std::vector```。 5. 将更新的“this”注入正在运行的函数中(这可能吗?)。
c++ vector undefined-behavior allocation
© www.soinside.com 2019 - 2024. All rights reserved.