返回指向矢量数据的指针,而不复制缓冲区和内存泄漏

Return pointer to vector's data without copying buffer and memory leaks

本文关键字:复制 缓冲区 泄漏 内存 指针 数据 返回      更新时间:2023-10-16

这个问题应该很简单,但我不是一个C++程序员。

因此,假设我有一个std::vector,其中填充了一些东西作为函数中的局部变量。我想做的是从该函数返回指向该数据和计数的指针,而不是向量本身(因为它转到另一种语言,而不是C++)。那么最好的方法是什么呢?

我敢打赌我可以用new关键字声明向量,但是当我稍后在其pointer data上调用free()时,会不会有泄漏?

我也可以malloc()新的缓冲区,将 vector 的缓冲区复制到其中并返回新的缓冲区,但我希望我能避免这种情况。

您可以使用std::vector<T>&声明函数作为参数并仅返回vector.count()(请参阅 C++ 中的通过引用传递)。后者,在客户端代码中将一个空的构造向量传递给该函数。

若要获取指向原始数据的指针,可以使用&vector[0]&vector.front()。从 C++11 开始,vector中新增了一个成员函数:data(),它返回容器中初始元素的地址。

通常,不要使用不必要的malloc/free操作,并避免在不必要的情况下使用堆分配。考虑使用智能指针而不是原始指针,考虑使用make_shared/make_unique而不是显式new

如果你的向量包含基本类型(例如int),并且你知道内存将被释放,你可以只使用:

if(v.empty()) return NULL;
int* retResut;
retResut= reinterpret_cast<int*>(std::malloc(v.size() * sizeof(int)));
std::memcpy(retResut,v.data(),v.size()* sizeof(int));
return retResut 

假设您需要声明一个具有以下定义的函数:SomeType* foo();.可以使用std::vector::data获取指向数据的原始指针 (c++11)。在 c++03 的情况下,您可以使用&my_vector[0](并且您必须检查空向量以避免运行时调试 aserts)

有一件事需要考虑;它是从多个调用的吗 线程与否:

  1. 当您只有一个线程调用foo时:

    std::vector<SomeType>& get_buffer()
    {
    static std::vector<SomeType> data;
    return data;
    }
    SomeType* foo()
    {
    std::vector<SomeType>& buffer = get_buffer();
    buffer.clear();
    //fill buffer with stuff with push_back
    return buffer.data();
    }
    
  2. 从多个线程调用时。静态变量已正确初始化,但push_back函数不是线程安全的。您还需要为每个线程使用不同的缓冲区,但这并不能保证完全安全(考虑到您无法知道该数据的生存期应该有多长)。get_buffer应为每个线程返回唯一的std::vector。您可以通过将static更改为thread_local来使用线程本地存储(请参阅此处):

    std::vector<SomeType>& get_buffer()
    {
    thread_local std::vector<SomeType> data;
    return data;
    }
    

    thread_local节点是自c++11如果您使用的是 c++03,则需要使用 boost 库或特定于平台的代码。