首页 > 解决方案 > 在运行时开始填充两个大向量

问题描述

我正在构建一个虚拟游戏经济,我的程序的第一个任务是用从数据库中检索到的项目填充两个结构向量。下面列出了我的两个结构。

项目对象是为数据库中有限的项目集创建的;PItems 保存数据库中的所有项目。PItems 的目的是经常修剪数据库。将它们一次加载到向量中就无需在运行时进行后续读取操作。

我遇到的问题是按顺序运行这两种方法。如果我在程序启动后调用这两个函数,名称值将填充垃圾字符。如果我只调用其中一个函数(任何一个),那么向量会被很好地填充,我可以遍历所有结构并很好地打印名称。我很好奇这是否是由于向量的动态分配。也许我有某种比赛条件。有趣的是,如果我运行这两个函数,所有整数值都会成功填充,但除非我只调用一个函数,否则永远不会填充 const char* 数据类型。

就目前而言,我只能调用一个函数或另一个函数,但不能同时调用两者。

我尝试将它们放在不同的线程上并在完成后加入它们,但到目前为止还没有成功。我也尝试过创建一个包含向量而不是多维向量的结构,但这也没有成功。

项目结构

struct Item
{
  const char* Name = "";
  uint16 ID    = 0;
  uint32 Price = 0;
  uint8  Stack = 0;
};

struct PItem
{
  const char* Name = "";
  uint16 ID = 0;
};

将项目加载到向量中的例程

extern CData* DB;
extern thread_local sqldata* SQL;

auto LoadBotItems(std::vector<std::vector<Item>> &Items) -> void
{
  Message::Status("Loading item lists");

  std::vector<Item> Ammo;
  std::vector<Item> Armor;
  std::vector<Item> Common;
  std::vector<Item> Food;
  std::vector<Item> Materials;
  std::vector<Item> Weapons;

  qresult Q = DB->Query(SQL, "SELECT Name, ID, Price, Qty, Cat FROM bot_data;");

  if (Q == PASS && DB->NumRows(SQL) != 0)
  {
    while (DB->NextRow(SQL) == PASS)
    {
      Item I;

      I.Name    = (const char*)DB->GetText(SQL, 0);
      I.ID      = (uint16)DB->GetUInt(SQL, 1);          
      I.Price   = (uint32)DB->GetUInt(SQL, 2);
      I.Stack   = (uint8 )DB->GetUInt(SQL, 3);
      uint8 Cat = (uint8 )DB->GetUInt(SQL, 4);

      if (Cat == 1)             // Ammo
        Ammo.push_back(I);
      else if (Cat == 2)        // Common
        Common.push_back(I);
      else if (Cat == 3)        // Weapon
        Weapons.push_back(I);
      else if (Cat == 4)        // Armor
        Armor.push_back(I);
      else if (Cat == 5)        // Materials
        Materials.push_back(I);
      else if (Cat == 6)        // Food
        Food.push_back(I);
    }
  }
  else
  {
    Message::Error("Could not load bot items!");
    return;
  }

  Items.push_back(Ammo);
  Items.push_back(Armor);
  Items.push_back(Common);
  Items.push_back(Food);
  Items.push_back(Materials);
  Items.push_back(Weapons);

  Message::Status("Bot items have been loaded.");
}

auto LoadPurgeItems(std::vector<PItem> &PItems) -> void
{
  qresult A = DB->Query(SQL, "SELECT ID, Name FROM Items WHERE Cat != 0;");

  if (A == PASS && DB->NumRows(SQL) != 0)
  {
    while (DB->NextRow(SQL) == PASS)
    {
      PItem I;
      I.ID   = (uint16)DB->GetUInt(SQL, 0);
      I.Name = (const char*)DB->GetText(SQL, 1);
      PItems.push_back(I);
    }
  }
  else
  {
    Message::Error("Could not load purge items!");
    return;
  }

  Message::Status("Purge items have been loaded.");
}

我试图在运行时开始填充两个向量。我没有为此使用最合适的数据结构吗?还是我以这种方式加载它们的逻辑错误?我需要实现线程和互斥锁吗?

标签: c++vectordata-structures

解决方案


最后,由于某种原因,我无法转换为 std::string 。还在想为什么。不过,出于我的目的,我将 const char* Name 更改为 char[20] Name 并使用了 strcpy。在那之后就像一个魅力一样工作。

编辑:

自从我发布这个已经有一段时间了,但我记得这是所有权和指针的问题。我需要在函数执行时在内存地址处制作数据的完整副本。之后,所有权丢失了,我指向的值已被覆盖。


推荐阅读