【问题标题】:Assigning std::vector to pointer inside a method将 std::vector 分配给方法内的指针
【发布时间】:2020-07-11 08:41:37
【问题描述】:

我想创建一个方法,它使用std::vectors 来建立数据集合,然后对数据进行一些操作,最后,我想通过给定参数的指针传递生成的信息,如图所示在这个小例子中:

struct MyStruct
{
    int* list;
    int entry_count;
};




static MyStruct createList()
{
   vector<int> vectorList;
   MyStruct data;

   vectorList.push_back(1);
   vectorList.push_back(1);
   vectorList.push_back(1);
   vectorList.push_back(1);
   vectorList.push_back(1);

   data.list = &vectorList.front();
   data.entry_count = vectorList.size();
   return data;
}

int main(int argc, char** argv)
{
   MyStruct data;
   data = createList();

   return 1;
}

问题是,方法关闭后,向量被销毁,指针无处显示。

我将如何以正确的方式处理这个问题?那么如何在不取消分配的情况下将此集合分配给指针呢?

【问题讨论】:

  • 如果你检查它,你会注意到main 中的list 仍然是空指针,而不是指向某个过期向量数据的指针。分配给函数的(非引用)参数在函数外部无效。

标签: c++ c++11 pointers stdvector lifetime


【解决方案1】:

您需要将函数设为本地 vectorListstatic 并使用 std::vector::data 通过指针获取底层数组。

void createList(int* list)
{
   static std::vector<int> vectorList;
   // ...
   list = vectorList.data();
}

但是,这使得vectorList 成为所有createList 函数调用中的唯一实例。如果您需要不同的vectorList 来进行不同的函数调用,我建议将所有内容包装到一个类中。

#include <vector>

class MyList /* final */
{
   std::vector<int> mVectorList;

public:
   // operations via functions

   int* data() /* const noexcept */  // ---> provide a member to acces the underlying data
   {
      return mVectorList.data();
   }
};

【讨论】:

  • 这意味着vectorList 的实例只有一次。这不是一个严重的限制吗?
  • @lubgr 使用类方法很好,但如果你只需要它用于小型用例,我觉得它有点矫枉过正。
【解决方案2】:

您需要对代码进行结构化,以使拥有的std::vector 超出使用指向其缓冲区的任何指针的范围。示例:

void createList(std::vector<int>& storage, int *first)
{
    storage.push_back(42);

    first = storage.data();
}

// in main, or any function:

std::vector<int> storage;
int *first = nullptr;

createList(storage, first);

在这里,我们将storage 作为引用(注意&amp;)传递,因此对其进行的任何更改都会对调用范围内创建的实际对象进行。

请注意,请务必记住,一旦您更改 storagefirst 可能是无效引用,因为 std::vector 在添加新元素时可能会重新分配并移动其缓冲区。

【讨论】:

  • 我的问题是,在调用该方法后我不再需要向量了。该方法创建了几个向量列表,具有不同的数据。然后将数据相互映射并将数据存储在特定结构中,并带有指向数据集合的指针。所以我需要向量来处理某个集合和映射函数。然后我想为所有信息分配一个带有指针的结构,然后删除向量。
  • 然后通过返回值传递你需要的数据。这更容易,而且通常不会因复制而导致任何运行时开销。
  • @DomiDiDongo 如果您要存储指向其数据的指针,那么只要您需要数据,就确实需要该向量。无法将该数据的所有权转移出向量。 (而且向量对象的开销可以忽略不计。)
  • 我编辑了示例以添加结构。是的,我必须保留向量是我试图避免的问题。那么有没有办法呢?所以必须在实例中绑定向量以保持数据活跃?
【解决方案3】:

根据您的用例,如果最初不需要创建向量,那么您可以按照以下方法。

#include <iostream>
#include <vector>

using namespace std;

int* createList()
{
    static std::vector<int> internalList;
    internalList.push_back(42);
    return internalList.data();
}


int main(int argc, char** argv)
{
    int *first = nullptr;
    first = createList();
    std::cout<<*first;

    return 0;
}

方法是声明一个静态向量,然后使用std::vector::data() 方法返回指向第一个元素的指针。 更多参考请关注C++ Documentation

【讨论】:

    猜你喜欢
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 2020-10-11
    • 2014-01-18
    • 2022-12-19
    • 2019-11-07
    • 1970-01-01
    • 2021-04-13
    相关资源
    最近更新 更多