首页 文章

C - 对于指向对象的指针向量,是否重新分配会导致删除和复制对象?

提问于
浏览
1

从我到目前为止的理解,如果你有一个类对象的向量,如果你擦除向量的任何成员,通常向量将重新分配它的一些对象,以保持内存连续性 . 因此,您需要为擦除矢量成员时要保留的所有内容实现三个规则(析构函数,复制构造函数和复制赋值运算符) .

但是:对于指向类对象的指针向量,结果对我来说不太清楚 . 如果我擦除一个成员,那么C肯定足够聪明,只需复制指针 - 不要疯狂地删除指针(以及它指向的类对象),然后重新创建它和它指向的对象?

如果不是这样,有人可以向我解释这个白痴吗?

2 回答

  • 1

    向量将单独保留指针值 . 它当然会在你推,弹出或擦除时移动内部数组中的值 .

    在这种情况下,值只是指针 . 但是,向量中没有逻辑来确定某些东西是否是指向对象的指针,并在复制值时删除/重新分配它们 .

    在包含复杂类型而不是指针的向量的情况下,当然会在重新分配或移动内部数组时尝试复制值 .

  • 1

    该向量将删除,构造和复制它包含的任何类型 . 在指向类/结构的指针向量的情况下,它将删除,构造和复制指针,使指针指向的实际对象单独存在 . 您可以自行分配和取消分配这些内容 .


    编辑

    一个例子:

    如果您有以下内容:

    class A
    {
      A() {}
    }
    
    void foo(void)
    {
       A * pointerToA = new A;
    }
    

    在函数foo的范围的末尾,唯一被解除分配的是变量 pointerToA 本身的内存,即保存地址(32位)的4个字节 - 在这种情况下存储在堆栈中 . 分配给新类A实例的内存的唯一方法是,如果手动调用delete,地址为 pointerToA .

    我们以类 A 的数组为例

    A ** arrayOfPointerToA = new A*[10];
    for(unsigned i = 0; i < 10; ++i)
      arrayOfPointerToA[i] = new A;
    

    这类似于 std::vector<A*> 时发生的情况 . 你打电话的时候

    delete [] arrayOfPointerToA;
    

    你要为 array of pointers 释放内存,而不是为每个 A 释放内存 .

    enter image description here

    在上图中,由上述删除调用解除分配的内存以红色突出显示 . 请注意,在这种情况下,每个 A 都存储在内存中的随机位置,因为它们都是单独分配的 .

    现在把它带到一个向量:

    std::vector<A> 有效地使用新的 A[size] 来分配内存 . 如果你要存储一个原始指针,这意味着它将分配一个类型为A的数组,这意味着创建了 size 类型为 A 的对象 . 当向量释放其内存 size 时,类型为 A 的对象数被销毁 . 现在采用该示例并用A *替换A,您将看到没有类型A的对象被销毁 .

    这是C和指针工作方式的基本部分,而不仅仅是容器的属性 . 如果容器在每个成员上任意调用delete,这就没有意义,因为当我们有一个容器 A 时,我们会在一个对象的实例上调用delete而不是指向该对象的无效指针 .

相关问题