将std :: vector :: data传递给期望类型**的函数(双指针)

时间:2019-12-02 09:12:16

标签: c++ pointers vector reference pass-by-pointer

正如标题所描述的,我正在尝试将指向std::vector的数据的指针传递给需要双指针的函数。以下面的代码为例。我有一个整数指针d,它以myfunc1的形式传递给&d(仍然不确定是否将其称为指针的引用或其他名称),其中该函数将其引用更改为用1,2,3,4填充的int数组。但是,如果我有一个std::vector的整数并尝试将&(vec.data())传递给myfunc1,则编译器将引发错误lvalue required as unary ‘&’ operand。我已经按照this answer尝试过类似(int *)&(vec.data())的方法,但是它不起作用。

仅供参考,我知道我可以做类似myfunc2的操作,在该操作中,我直接将向量作为参考传递,并且工作已完成。但是我想知道是否可以在std :: vector的指针中使用myfunc1

任何帮助将不胜感激。

#include <iostream>
#include <vector>


using std::cout;
using std::endl;
using std::vector;

void myfunc1(int** ptr)
{
    int* values = new int[4];
    // Fill all the with data
    for(auto& i:{0,1,2,3})
    {
        values[i] = i+1;
    }

    *ptr = values;
}

void myfunc2(vector<int> &vec)
{
    int* values = new int[4];
    // Fill all the with data
    for(auto& i:{0,1,2,3})
    {
        values[i] = i+1;
    }

    vec.assign(values,values+4);
    delete values;
}

int main()
{
    // Create int pointer
    int* d;

    // This works. Reference of d pointing to the array
    myfunc1(&d);

    // Print values
    for(auto& i:{0,1,2,3})
    {
        cout << d[i] << " ";
    }
    cout << endl;

    // Creates the vector
    vector<int> vec;

    // This works. Data pointer of std::vector pointing to the array
    myfunc2(vec);

    // Print values
    for (const auto &element : vec) cout << element << " ";
    cout << endl;

    // This does not work
    vector<int> vec2;
    vec2.resize(4);

    myfunc1(&(vec2.data()));

    // Print values
    for (const auto &element : vec2) cout << element << " ";
    cout << endl;

    return 0;
}

编辑:我的实际代码是从磁盘读取一些二进制文件,并将部分缓冲区加载到向量中。我在将修改后的向量从读取函数中删除时遇到了麻烦,这就是我想出的解决办法。

2 个答案:

答案 0 :(得分:2)

当您写: myfunc1(&(vec2.data()));

您正在获取右值的地址。尖头的int*是如此临时,可以在调用后立即销毁。

这就是为什么您会收到此错误。

但是,正如 @molbdnilo 所说,在您的myfunc1()函数中,您正在重新分配指针(不必担心破坏以前分配的内存) 。
但是std::vector已经自行管理其数据存储器。您不能,也不能把手放在上面。


  

我的实际代码要做的是从磁盘读取一些二进制文件,并将部分缓冲区加载到向量中。

解决方案可能是通过将迭代器传递到所需部分的开头并将迭代器传递到所需部分的末端以提取构造函数的参数来构造std::vector

例如:

int * buffer = readAll("path/to/my/file"); // Let's assume the readAll() function exists for this example

// If you want to extract from element 5 to element 9 of the buffer
std::vector<int> vec(buffer+5, buffer+9);

如果std::vector已经存在,则可以像在assign()中一样使用myfunc2()成员函数:

vec.assign(buffer+5, buffer+9);

当然,在两种情况下,您都必须确保在访问缓冲区时不要尝试访问超出范围的元素。

答案 1 :(得分:0)

问题在于您不能使用data()的地址,因为它只是指针的临时副本,因此向其写入指针没有太大意义。这样很好。您不希望将data()传递给此函数,因为它将用新数组覆盖指针,这将破坏向量。您可以从函数中删除一个*,而仅将其分配给该函数,而不在其中分配内存。这将起作用,但是请确保在调用方中分配内存(使用resize时,仅reserve会导致未定义的行为,因为data()只是指向有效开头的指针。范围[data(), data() + size())。范围[data(), data() + capacity ())无效。