指向向量元素的c++指针,元素已删除
C++ pointer to vector element, element erased
我希望…
有一个元素向量。元素是我自己的类类型。维护一个指向该vector的特定成员的指针。
问题是:如果从vector中移除元素,指针会发生什么变化?
潜在:
- 当遍历vector时,是否有任何方法可以检查迭代器是否指向我当前拥有指针的元素?
vIterator == pElement
会这么做吗? - 是否有任何方法从向量中删除元素,只有指向该元素的指针?如果前一个问题的答案是肯定的,那么我想我可以用循环来实现它。
提前感谢!
- 它现在将指向无效内存a或指向不同的对象。一般来说,使用指针现在是未定义的行为。
-
if(&*vIterator == ptr) ...
其中
*
从迭代器获得对象的引用,&
给出它的地址。注意,虽然&*
对指针是无操作的,但这里我们需要它,因为迭代器重载了*
。 -
你可以用线性搜索,但这是不必要的低效。您可以利用存储是连续的这一事实,并执行:
vec.erase(vec.begin()+(ptr-&vec[0]));
ptr-&vec[0]
根据通常的指针运算给出了vector中的索引,将其添加到begin迭代器中会得到指向它的迭代器。
。从技术上讲,vector不允许在移除元素时释放内存,所以说它可能指向一个无效(=已经销毁)的对象可能更正确。
指针删除对象
这在很大程度上取决于你如何将类存储在vector中。让我们假设,您正在按照以下方式进行操作:
std::vector<MyClass> classes;
如果您查看std::vector
的构造函数,您将看到,它还接受另一个参数,分配器。这是因为vector负责为它保存的项分配和释放内存。
如果使用上述符号,每次向vector中添加元素时,vector都会分配内存,并在移除元素时释放内存。因此,如果你保留了一个指向vector中某个元素的指针并将其移除,那么该指针将指向无效的内存(释放的对象),你不应该再使用它。
如果按照以下方式保存对象,情况就不同了:
std::vector<MyClass *> classes;
在这种情况下,vector只负责保持指针指向类,并分配和释放指针(不考虑它们指向什么)。然后负责创建和销毁指向vector中保存的指针的元素。
有一种简单的方法来检查迭代器是否指向特定对象。首先,解引用迭代器以获得实际对象:(*iter)
,然后询问该对象的地址:&(*iter)
,并检查它是否与你有指针指向的对象匹配。
删除
是的,可以——例如,简单地使用循环。如果您将实际对象保留在矢量中(我提到的第一个选项),Matteo建议的选项将起作用。这是因为vector应该将其所有数据保存在一个连续的内存块中,并且当您有指向它的指针(指针算术)时,很容易计算对象的索引。
您的vector拥有对象,但您也希望能够使用它们的指针删除它们。如果直接将它们存储在vector中,则无法清楚地实现这一点,因为正如您所怀疑的那样,在改变vector的大小时,vector可能会进行重新分配,并且在vector中间插入或删除将使指向下一个元素的所有指针失效。
这就是std::unique_ptr发挥作用的地方。通过在vector中保留智能指针,您仍然可以保留所有权,而不必处理内存管理,并且无效也不是问题:
std::vector<std::unique_ptr<CustomClass>> objects;
std::unique_ptr<CustomClass> object(new CustomClass());
objects.push_back(std::move(object));
现在假设object_pointer有你的一个对象的地址,你可以删除那个对象而不用担心无效:
objects.erase(
std::remove_if(objects.begin(), m_objects.end(),
[&](const std::unique_ptr<CustomClass>& ptr) { return ptr.get() == object_pointer; }),
objects.end()
);
问题如果我从向量中删除元素,指针会发生什么?
以下是std::vector:erase
删除元素
从
vector
中删除单个元素(position
)或一系列元素([first,last)
)。这有效地减少了容器的大小,通过删除元素的数量,这些元素被销毁。
由于
vector
使用数组作为其底层存储,因此擦除除vector端以外位置的元素会导致容器将擦除段后的所有元素重新定位到新位置。与其他类型的序列容器(如list
或forward_list
)执行相同的操作相比,这通常是一个效率低下的操作。
我不清楚这些元素是否需要被重新定位到现有内存中,或者编译器可以自由地为元素分配新内存并将元素重新定位到新内存中,然后删除旧内存。
最好的情况是元素被重新定位到现有内存中。即使这样…
如果你有一个指针指向vector
的第n个元素,而vector
的大小小于n
,那么你持有的是一个悬空指针。如果访问指针,可能会得到未定义的行为。如果vector
中的元素数大于或等于n
,则指向一个新对象,但它仍然是一个有效对象。
Question当遍历vector对象时,是否有办法检查迭代器是否指向当前指针所指向的元素?vIterator == pElement能做到吗?
答案您可以使用:
检查是否有元素的地址if (myptr == &(*iter))
问题是否有一种方法可以仅使用指向该元素的指针从vector中删除该元素?
答案既然上一题的答案是"是",那么这一题的答案也是"是"。
- C++如何通过用户输入删除列表元素
- 使用函数"remove"删除重复元素
- 如何通过 getter 函数删除矢量的元素?
- 从控制台中删除最后打印的元素
- 如何从存储在std::映射中的std::集中删除元素
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 删除列表中的第n个元素
- 从矢量中删除元素后出现隔离错误
- 删除映射和分割错误中的一个过去结束元素
- 如何使用remove_if从矢量中删除元素
- 如何从使用 for 循环中的矢量大小的矢量中删除元素
- 从矢量中删除空元素
- 关于比较两个无序数组并删除 a[] 中可以在 b[] 中找到的元素的问题
- 删除指针数组 (C++) 中的元素
- 删除列表 c++ 中的最后 3 个元素
- 比较 2 个向量并从第二个向量中删除在第一个 - c++ 中找不到的元素
- 为什么通过 vector<reference_wrapper> 的元素删除引用的值<T>不会使向量无效?
- 从std::multiset的第i个元素删除到末尾
- 删除 [] 是否等于每个元素删除.C++
- std::列出元素删除后节点的内存回收