【问题标题】:C++ puttting one element of vector to another vectorC ++将向量的一个元素放入另一个向量
【发布时间】:2013-06-22 19:29:12
【问题描述】:

我正在使用 SDL 开发 RTS 游戏。我有一个木场类,其对象将从附近的树木中收集木材。在类中,我创建了一个名为 temp_trees 的向量,并作为构造函数的参数,我使用了一个传入的树对象向量。

木场构造函数:

woodyard::woodyard(int x, int y, int HP, int id, vector<Tree> trees)
{
...
vector<Tree> temp_trees;
for(int i = 0; i < trees.size(); i++)
{
    if((trees[i].xPos - 100) / 50 >= x - 5 && (trees[i].xPos - 100) / 50 <= x + 4)
    {
        if((trees[i].yPos - 100) / 50 >= y - 5 && (trees[i].yPos - 100) / 50 <= y + 4)
        {
            temp_trees.push_back(trees[i]);
        }
    }
}

collect_control = 0;
no = 0;
}

collect_wood 函数:

void woodyard::collect_wood(){
if(no == 5)
{
 temp_trees[collect_control].drewno -= 1;
 if(temp_trees[collect_control].drewno <= 0){
 collect_control++;
 temp_trees.erase(temp_trees.begin());
}}


no++;
if(no >= 10){
  no = 0;
}}

程序在启动后立即崩溃。 任何人都可以看到这段代码中的任何错误吗??

PS:我想在构造函数中将元素从一个向量复制到另一个向量可能有问题。

【问题讨论】:

  • 你是通过调试器运行的吗?调试器在哪里停止?它给了你什么错误?
  • 它停在“temp_trees[collect_control].drewno -= 1;”
  • temp_trees 声明在哪里,WRT collect_wood 方法?
  • temp_tree 在woodyard 类的构造函数中(在post 中) collect wood 在woodyard 的头文件中声明
  • 当它停在该行时:a)collect_control 的值是多少,b)temp_trees 的大小是多少?

标签: c++ class vector copy sdl


【解决方案1】:

构造函数不包含任何非法操作。

而collect_wood()虽然难以理解,但没有包含任何使其崩溃的明显原因。

collect_control 的值是多少?你检查它是否是&lt; temp_trees.size()?请注意,temp_trees.size() 会不断变化,因为您正在擦除元素。

可能collect_control 不应该在擦除后递增:所有元素都向后移动,并且在擦除后 collect_control 已经指向下一个元素。

注意:考虑到temp_trees.erase(temp_trees.begin()); 是您可以对向量执行的最低效的操作之一(删除第一个元素)。

【讨论】:

  • 我不检查 temp_trees 大小的原因是它正在发生变化。 collect_control 值决定了 Tree 对象的使用顺序。它在开始时设置为 0,并在每次当前 Tree 对象用完和销毁时递增。这使得函数从向量中的第一棵树开始,到时候删除第一棵树
  • @user2466076 至少在调试时检查 collect_control before 语句如 temp_trees[collect_control] 会以何种方式损害?
【解决方案2】:

在woodyard 构造函数中,您声明了一个临时的、函数范围的变量“temp_trees”。

woodyard::woodyard(int x, int y, int HP, int id, vector<Tree> trees)
{
...
vector<Tree> temp_trees;

如果您有一个名为 temp_trees 的向量成员,则此声明将隐藏它。所以你的成员函数没有看到相同的向量:

void woodyard::collect_wood(){
if(no == 5)
{
 temp_trees[collect_control].drewno -= 1;

另外,如果没有看到其余代码,我不知道您如何确保向量中至少有“collect_control”成员。

#include <assert.h>
...
assert(collect_control < temp_trees.size());

或者如果你使用的是 Visual Studio,你可以这样做

if(collect_control >= temp_trees.size())
    DebugBreak();

"size()" 是一个从 1 开始的值,但数组索引运算符是从零开始的。这意味着,当向量中有一个条目时,它将是向量[0]。如果向量为空,则向量[0] 是非法的——它不存在。空值由大小为 0 表示。大小必须始终大于您尝试访问的元素索引。

【讨论】:

  • 我的错误是在标题中声明了 temp_trees 向量
  • 那么问题是它是空的。 size() == 0 表示为空,因此您无法访问 temp_trees[0] 因为没有元素。 (见编辑答案的最后一段)
  • temp_trees[...].drewno = -1 之前。它会触发,因为您试图访问没有元素的第一个元素。
  • 鉴于您显示的代码,问题是您在构造函数中有一个私有的“temp_trees”,或者问题是您没有向向量中添加任何树。
  • 这是因为 (a) 您有两个称为“temp_trees”的向量 - 标题中的一个和您在构造函数中声明的一个,(b) 您的逻辑无法添加任何成员。结果是向量中没有元素对“collect_wood()”可见。这就是 size() 为零的原因。这意味着“此向量为空”,因此将 [] 运算符与 ANY 值一起使用是非法的。 temp_tress[0] 不合法,因为没有元素。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多