【问题标题】:Use of pointer to vector which involved the use of 'new'使用指向向量的指针,其中涉及使用“新”
【发布时间】:2023-03-28 06:34:01
【问题描述】:

我想创建一个 指向结构的指针向量

vector<myStruct*> vec

对于向量中的元素,并非所有元素都包含数据。其中一些可能指向NULL。 那么,我是否应该首先在每个元素中通过new 创建空间

for(int i = 0; vec.size() ;i++){
       if (thisSpaceIsValid(i))
             vec.at(i) = new myStruct;
         else
             vect.at(i) = NULL;
}

问题来了:
- 如果我为每个元素使用new,它会很慢。我怎样才能加快速度?有没有办法创建我需要的所有空间,自动访问这些空间的指针到向量(vec 这里)?

-如果以后我用delete来释放内存,速度的问题还会困扰我吗?

【问题讨论】:

  • 这可能是您了解智能指针的好机会:en.cppreference.com/w/cpp/memory/shared_ptr。如果您使用的是 C++11 之前的编译器,则可以使用与 boost 库相同的功能。
  • "如果我对每个元素都使用 new,它会很慢。" 什么会很慢?初始化向量?使用它?
  • 如果你想提高性能,你仍然可以声明myStruct tab[max],但是空闲内存可能会很微妙
  • 如果您担心单独分配,请使用您自己的分配方案...
  • 您确定动态内存分配本身的性能是您应该担心的吗?

标签: c++ pointers vector


【解决方案1】:

如果我对每个元素都使用“新”,那会很慢。我怎样才能加快速度?有没有办法创建我需要的所有空间,自动将这些空间的指针访问到向量(此处为“vec”)?

你可以这样做。

假设您的vector 的大小是M,而您只需要这些元素中的N 具有指向对象的指针,而其他元素是空指针。您可以使用:

myStruct* objects = new myStruct[N];

然后,使用:

for(int i = 0, j = 0; vec.size(); i++)
{
   if (thisSpaceIsValid(i))
   {
      if ( j == N )
      {
         // Error. Do something.
      }
      else
      {
         vec[i]  = objects+j;
         ++j;
      }
   }
   else
   {
      vect[i] = NULL;
   }
}

您现在必须确保您能够跟踪objeccts 的值,以便您可以安全地使用释放内存

delete [] objects;

附言

对于您的问题,可能会有更好、更优雅的解决方案。多花点时间思考一下是值得的。

【讨论】:

  • 以这种方式使用结构是否安全?填充是什么?
  • @EdgarRokyan,当然是安全的。编译器会处理填充。
  • 虽然这很优雅,但它给我们留下了安全和一致的指针清理的可怕困境。
  • @SergeyA,我同意。对于 OP 的实际问题,可能有更优雅的解决方案。
  • @RSahu,如何使用shared_ptr而不是普通指针创建类似于myStruct* objects = new myStruct[N];的数组?
【解决方案2】:

编辑:

再次阅读问题后,我似乎误解了这个问题。所以这是一个经过编辑的答案。

如果您只需要在某种初始化阶段执行代码,您可以在一个数组中创建 myStruct 的所有实例,然后按照 R Sahu 已经提出的那样从向量中指向这些实例。请注意,该解决方案要求您同时创建和删除所有实例。

但是,如果您多次执行此代码和/或不确切知道需要多少个 myStruct 实例,您可以为结构覆盖 new 和 delete 并自己处理内存分配。

有关此示例,请参阅 Callling object constructor/destructor with a custom allocator。请参阅 Jerry Coffin 的答案。

顺便说一句——你不需要vec.at(i),因为你正在从 0 迭代到 size。 vec[i] 还可以,应该会更好。

旧答案:

你可以的

vector<myStruct*> vec(10000, nullptr);

生成一个向量,例如 10000 个元素全部初始化为 nullptr

之后,您可以使用指向结构的指针填充相关元素。

只给delete

for (auto e : vec) delete e;

因为在 nullptr 上执行 delete 是安全的

【讨论】:

  • 从问题中我可以理解,问题是new 的大量使用,它对性能的影响。在这种情况下,您的回答并没有真正的帮助。
  • @EdgarRokyan - 再次阅读问题后,我认为您是对的。看来我只是误解了这个问题。嘘……发生了。
【解决方案3】:

如果你需要一个指针向量,并且想避免调用 new,那么首先自己创建一个结构容器,然后将指向元素的指针分配给你的 vec。选择结构容器时要小心。如果使用结构体的向量,请确保提前保留所有元素,否则当向量增长时,其元素可能会移动到不同的内存位置。另一方面,双端队列保证其元素不会移动。

当性能很重要时,应尽可能在 c++ 中避免多次小的 new 和 delete 调用。

【讨论】:

    【解决方案4】:

    我想得越多,我就越不喜欢@RSahu 的解决方案。特别是,我觉得这种情况下的内存管理将是一场噩梦。相反,我建议使用通过自定义分配器分配的 unique_ptr 拥有内存的向量。我相信,顺序分配器会做。

    【讨论】:

      猜你喜欢
      • 2015-06-17
      • 1970-01-01
      • 2011-08-04
      • 2014-04-02
      • 1970-01-01
      • 2015-06-23
      • 2022-11-11
      • 2012-11-18
      • 1970-01-01
      相关资源
      最近更新 更多