【问题标题】:For loop in C++ stops after a single iteration w/ pointer variableC ++中的for循环在带有指针变量的单次迭代后停止
【发布时间】:2021-04-04 11:20:30
【问题描述】:

所以首先我会用:我刚开始使用 c++。

我有一个结构,我将指向的指针存储在 unordered_map 中,当我通过我的流程获取成员时,在结构指针中设置成员的值。然后我在地图中不再需要它们,因此我将它们转移到矢量并循环遍历它们。

虽然在第二个循环中,它输出了我的索引 (1),但是下一条为该索引处的结构创建本地指针 var 的语句破坏了它,并且代码终止而没有任何错误。因为没有错误,所以 try/catch 也没有给我任何东西。


// Wanted to create a structure to handle the objects easier instead
//  of multiple vectors for each property
struct appData {
    std::string id = "";
    std::string name = "";
    std::string vdf_file = "";
    std::string vdf_path = "";
};

// Relevant parts of my main()
int main() {

  // Map that stores all the struct pointers
  std::unordered_map<std::string, appData*> appDatas;
  
  char memory[sizeof(appData)];
  void* p = memory;
  // New instance of appData
  appData *tempAppData = new(p) appData();
  tempAppData->appid = "86901";
  // Add tempAppData to map with string key
  appDatas["86901"] = tempAppData;

  ...

  std::vector<appData*> unhashed_appDatas;
  for (auto const& pair: appDatas) {
    unhashed_appDatas.push_back(pair.second);
  }

  ...
 
  for (unsigned int x = 0; x < unhashed_appDatas.size(); x++) {
    // Output index to see where it was messing up
    std::cout << x << std::endl;
!!  // This is where the issue happens on the second loop (see output)
    appData *thisAppData = unhashed_appDatas[x];
    std::string id = thisAppData->appid;
    std::cout << id << std::endl;
    /* ...
       Do more stuff below
    */
  }

  ...

  return 0;
}

Terminal Output:
0               // Initial index of x
86901           // Id of first item
1               // New index of x on second loop before pointer var is created
                // Nothing more is printed and execution terminates with no errors

我对 c++ 的了解非常缺乏,几天前就开始了,所以在我的知识范围内我尝试了几件事:将 *thisAppData 变量移到循环之外,使用 for(var: vector) { ... } 和一个 while 循环.我可以假设问题在于循环内部的指针和局部变量。 任何有关如何更好地解决此问题或我的代码是否存在问题的帮助/输入将不胜感激:)

编辑:根据@Jarod42 的回答,将代码更改为使用.size() 而不是sizeof(),但主要问题仍然存在

Edit2:原来是我自己搞砸了,想象一下。凌晨 4 点的大脑工作不太好——posted answer 关于我做错了什么。感谢所有帮助过我的人

【问题讨论】:

  • 如果您缺乏 c++ 知识,那么在具有自动存储持续时间的缓冲区上使用放置 new 可能不是最明智的方法。
  • 不要使用手动内存管理(不要使用new / delete)。使用标准容器,例如std::vector
  • 你不必使用placement new,你可以使用regular new。更明智的是,您可以使用std::unique_ptr,或者如果您不使用继承,则只使用普通对象。
  • @jarod 我有一个来源的数据,我从 7 个不同的来源收集了很多数据!复数复数,bwahahahaha。 (我开玩笑)OTOH,在那一集中,时间旅行确实产生了多个数据……;)

标签: c++ windows gcc


【解决方案1】:

sizeof 在这里是错误的工具:

for (unsigned int x = 0; x < sizeof(unhashed_appDatas); x++) {
//                           ^^ wrong: give **static** size of the structure
// mainly 3 members (data, capacity, size), so something like `3*sizeof(void*)`

应该是

for (unsigned int x = 0; x < unhashed_appDatas.size(); x++) {

【讨论】:

  • 似乎我在搞砸的时候不小心把它改成了sizeof,现在我已经更新了我的代码以使用.size(),谢谢。尽管主要问题仍然存在。
  • 您的新展示位置很奇怪,但您只显示“有效”的插入,而不是第二个...
【解决方案2】:

经过数小时的反复试验,我确定了问题所在(除了以我应该做的方式做事,我已经更正了)这是我搞砸了导致这个问题的原因。

TLDR:

我认为存在的项目不存在,并尝试读取具有空白路径的文件并解析不存在的内容。


说明:

在第一个循环中,我得到的数据是一个目录中的文件列表,然后解析一个类似 json 的文件,其中包含这些文件名和与之关联的属性。虽然,文件列表包含不在这个其他数据文件中的条目(因为我没有检查它们是否存在)所以它会在那里中断。 此外,在最后一个循环中,我将从结构中获取一个成员,该成员将是要读取的文件的路径,但它会是空白的(未设置),因为它不存在于数据文件中,因此std::ifstream file(path); 会破坏它。 我已经对每个键和值进行了检查,以确保它不会再因此而中断。


修复:

以下是我添加到代码中的一些修复,确实帮助它最终正常工作,即使它们不是我自己造成的主要问题:

// Thanks to @EOF:
// No longer "using placement new on a buffer with automatic storage duration"
// (whatever that means haha) and was changed from:
  char memory[sizeof(appData)];
  void* p = memory;
  appData *tempAppData = new(p) appData();
// To:
  appData *tempAppData = new appData();
// Thanks to @Jarod42:
// Last for loop limit expression was corrected from:
  for (unsigned int x = 0; x < sizeof(unhashed_appDatas); x++) {
  } 
// To:
  for (unsigned int x = 0; x < unhashed_appDatas.size(); x++) {
  }
// I am still using a map, despite comment noting to just use vectors
// (which I could have, but just would prefer using maps):
  std::unordered_map<std::string, appData*> appDatas;
// Instead of doing something like this instead (would have arguably have been easier):
  std::vector<std::string> dataKeys = { "1234" };
  std::vector<appData*>    appDatas = {   ...  };
  auto indx = find(dataKeys.begin(), dataKeys.end(), "1234");
  indx = (indx != dataKeys.end() ? indx : -1);
  if (indx == -1) continue;
  auto dataItem = appDatas[indx];
// 

感谢大家对我的代码的帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多