简体   繁体   English

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

[英]Passing std::vector::data to function expecting type** (double pointer)

As the title describes, I am trying to pass the pointer to the data of a std::vector into a function expecting a double pointer.正如标题所描述的,我试图将指向std::vector数据的指针传递给一个需要双指针的函数。 Take as an example the code below.以下面的代码为例。 I have an int pointer d which is passed to myfunc1 as &d (still not sure if call it the pointer's reference or what), where the function changes its reference to the beginning of an int array filled with 1,2,3,4 .我有一个 int 指针d ,它作为&d传递给myfunc1 (仍然不确定是否将其称为指针的引用或什么),其中函数将其引用更改为填充了1,2,3,4的 int 数组的开头。 However, if I have a std::vector of ints and try to pass &(vec.data()) to myfunc1 the compiler throws the error lvalue required as unary '&' operand .但是,如果我有 int 的std::vector并尝试将&(vec.data())传递给myfunc1编译器会抛出错误lvalue required as unary '&' operand I have already tried something like (int *)&(vec.data()) as per this answer , but it does not work.我已经按照这个答案尝试了(int *)&(vec.data())类的东西,但它不起作用。

Just for reference, I know I can do something like myfunc2 where I directly pass the vector as reference and the job is done.仅供参考,我知道我可以做一些类似myfunc2事情,我直接将向量作为参考传递,然后工作就完成了。 But I want to know if it's possible to use myfunc1 with the std::vector's pointer.但我想知道是否可以将myfunc1与 std::vector 的指针一起使用。

Any help will be very much appreciated.任何帮助将不胜感激。

#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;
}

EDIT: What my actual code does is to read some binary files from disk, and load parts of the buffer into the vector.编辑:我的实际代码所做的是从磁盘读取一些二进制文件,并将缓冲区的一部分加载到向量中。 I was having troubles getting the modified vector out of a read function, and this is what I came up with that allowed me to solve it.我在从读取函数中获取修改后的向量时遇到了麻烦,这就是我想出的办法,让我能够解决它。

When you write: myfunc1(&(vec2.data()));当你写: myfunc1(&(vec2.data()));

You are getting the address of a rvalue.您正在获取右值的地址。 The pointed int* is so a temporary that is destroyed right after the call.指向的int*是一个临时的,在调用后立即销毁。

This is why you get this error.这就是您收到此错误的原因。

But, as @molbdnilo said, in your myfunc1() function, you are reassigning the pointer (without caring to destroy previously allocated memory by the way).但是,正如@molbdnilo所说,在myfunc1()函数中,您正在重新分配指针(顺便说一下,不关心破坏先前分配的内存)。
But the std::vector already manages its data memory on its own.但是std::vector已经自行管理其数据内存。 You cannot and you must not put your hands on it.你不能也不能把手放在上面。


What my actual code does is to read some binary files from disk, and load parts of the buffer into the vector.我的实际代码所做的是从磁盘读取一些二进制文件,并将缓冲区的一部分加载到向量中。

A solution could be to construct your std::vector by passing the iterator to the beginning and the iterator to the end of the desired part to extract in the constructor's parameters.一种解决方案可能是通过将迭代器传递到开头并将迭代器传递到所需部分的末尾来构造std::vector以在构造函数的参数中提取。

For example:例如:

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);

If the std::vector already exists, you can use the assign() member function as you already did in myfunc2() :如果std::vector已经存在,您可以像在myfunc2()那样使用assign()成员函数:

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

Of course in both cases, you have to ensure that you are not trying to access an out of bounds element when accessing the buffer.当然,在这两种情况下,您都必须确保在访问缓冲区时不会尝试访问越界元素。

The problem is that you cannot take the address of data() , since it is only a temporary copy of the pointer, so writing to a pointer to it makes not that much sense.问题是您不能获取data()的地址,因为它只是指针的临时副本,因此写入指向它的指针没有多大意义。 And that is good that way.这样很好。 You DO NOT want to pass data() to this function since it would overwrite the pointer with a new array and that would break the vector.您不想将data()传递给这个函数,因为它会用新数组覆盖指针,这会破坏向量。 You can remove one * from the function and only assign to it and not allocate the memory there.您可以从函数中删除一个*并且只分配给它而不在那里分配内存。 This will work, but make sure to allocate the memory in the caller (with resize , just reserve will result un undefined behavior, since data() is only a pointer to the beginning of the valid range [data(), data() + size()) .这会起作用,但请确保在调用者中分配内存(使用resize ,只reserve会导致未定义的行为,因为data()只是指向有效范围[data(), data() + size()) The range [data(), data() + capacity ()) is not necessary valid.范围[data(), data() + capacity ())不一定有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM