【问题标题】:C++ - Safety of accessing element of vector via pointersC++ - 通过指针访问向量元素的安全性
【发布时间】:2015-10-18 06:27:15
【问题描述】:

在我的一个 C++ 项目中,我使用 vector 来保存一堆 structs,其中包含一些简单游戏的元素(即:井字游戏、坐标、xo 等)。即:

struct gameMove
{
  int x;
  int y;
  int player;
  int order;
};

在单场比赛中,每当玩家移动时(即:放置xo),信息通过push_back() 存储在vector 中,以创建“撤消”功能,目前按预期工作。

在我的撤消/重做逻辑的某些部分,我使用了遍历vector、找到适当元素并直接返回指向该元素的指针的函数。

只要我正确地管理vector,访问它,将所有指向vector 元素的指针清空,它是否安全,或者是否存在固有风险?我担心的是,如果扩展我计划做的游戏(即:对我正在开发的国际象棋游戏使用相同的代码),并且vector 变得太大,需要自动重新分配,指针将变得无效(即:整个列表被移动到一个可以容纳所有元素的新连续块),或者是否有某种类型的智能指针接口到 vector 来完成同样的事情?

谢谢。

【问题讨论】:

    标签: c++ vector stdvector type-safety


    【解决方案1】:

    您的担心是正确的:如果向量需要增长,vector 中的地址将会改变(或者如果向量缩小,但vector 的大多数实现不会在没有程序员努力的情况下缩小)。

    直接简单的解决方案是将索引返回到向量中,而不是指针。只要它在范围内,那将始终是查找特定元素的有效方法。 [而不是NULL,您可以使用例如-10xDEAD]

    【讨论】:

    • 如果我确定了vector中元素数量的上限,是否可以提前设置最大vector大小,保证它永远不会重新调整大小?跨度>
    • @Dogbert 您可以使用reserve 提前分配您需要的内存,但是如果您可以使用索引而不是指针,那么为什么要麻烦,正如这个答案所提到的那样?跨度>
    • 如前所述,reserve 将保证vector 不会被重新分配[直到达到保留限制],但我看不到好处......除非你计划在超过 40 亿条记录中,指针大于整数 [在 64 位架构中,这是当今的常态,即使在手机上也是如此!]
    • 除非在 C++11 中进行了更改,否则 vector 保证不会在删除元素或使用小于当前容量的值调用 reserve() 时重新分配。从 C++03 标准的 23.2.4.2/2 开始:“当且仅当当前容量小于 reserve() 的参数时,才会在此时发生重新分配。”
    • @JorenHeit 我想避免使用索引方法的原因是因为它需要内部 API 重写,如果安全可能,我想避免这种方法,并且可能使用全局变量。
    【解决方案2】:

    您是否考虑过使用std::stackstd::list?堆栈对于简化您正在寻找的“撤消”功能尤其具有吸引力(因为最后一步将始终是堆栈的顶部)。但是使用链接结构,您不必担心索引问题,但如果您的内存紧张,它们可能不是最佳选择...

    【讨论】:

      猜你喜欢
      • 2018-12-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-19
      • 2014-07-26
      • 1970-01-01
      • 2012-06-07
      相关资源
      最近更新 更多