将c-array分配给c ++向量

时间:2016-08-31 08:21:54

标签: c++ arrays vector

我有一个关于onstack创建数组的生命周期以及将它们转换为c ++向量的问题。对于前者,我有两个功能:

void getVector()
{ 
    auto myVector = createVectorFromArray();
}

vector<float> createVectorFromArray()
{
    float myArr[10];
    readDataFromSomewhere(myArr, 10); //some read data function with signature void(float*, size_t)
    vector<float> resVector;
    resVector.assign(myArr, myArr+10);
    return resVector;
}

据我所知,当我们离开函数 createVectorFromArray 时,阵列 myArr 将被终止。因此函数 getVector 中向量 myVector 的迭代器将指向无处。我是对的,还是以另一种方式工作?在这种情况下,如何从数组中更好地生成向量以从函数返回?

谢谢!

3 个答案:

答案 0 :(得分:3)

您可以像这样重写createVectorFromArray,并且在将数组分配给矢量时不会有任何麻烦:

vector<float> createVectorFromArray()
{
    vector<float> resVector(10);

    readDataFromSomewhere(&resVector[0], resVector.size());

    return resVector;
}

std::vector是连续的内存容器,因此您可以将它用作普通旧C函数的接口

答案 1 :(得分:2)

这个答案旨在讨论各种方法,解释它们,并将它们置于上下文中。

选项1:矢量副本的原生:

vector<float> createVectorFromArray()
{
    // data copied once
    float myArr[10];
    readDataFromSomewhere(myArr, 10);

    // vectors are lightweight handles. zero-cost construction
    // since the optimiser will see that the next statement assigns to
    // the vector
    vector<float> resVector;

    //
    // data copied twice
    //
    resVector.assign(myArr, myArr+10);

    //
    // it's almost guaranteed that RVO will elide this copy. As of c++17
    // it's a guarantee. Returning the vector is fine
    return resVector;
}

问题:

  1. 数据复制两次
  2. vector将需要内存分配
  3. 选项2:直接使用向量

    vector<float> createVectorFromArray()
    {
        // Will allocate space and
        // default-initialise the floats (i.e. they won't be initialised)
        vector<float> resVector(10);
    
        //
        // one data copy. perfectly safe and idiomatic.
        // std::addressof expressed intent clearly.
        //
    
        readDataFromSomewhere(std::addressof(resVector[0]), resVector.size());
    
        //
        // it's almost guaranteed that RVO will elide this copy. As of c++17
        // it's a guarantee. Returning the vector is efficient.
        return resVector;
    }
    

    问题:

    1. vector将需要内存分配
    2. ...更好

      选项3:重用现有的载体

      void createVectorFromArray(vector<float>& resVector)
      {
          //
          // if resVector has been used before and has a capacity() of 10
          // or more, no memory allocation necessary
          //
          resVector.resize(10);
      
          // one copy of data
          readDataFromSomewhere(std::addressof(resVector[0]), resVector.size());
      }
      

      问题:

      1. 或许不太容易使用参考界面。
      2.   

        我如何在选项2和3之间进行选择?

        选项2更具可读性(恕我直言),但如果在循环中使用则会很昂贵。所以对于一次性,我会去那。

        如果我在循环中将数据读入缓冲区,我可能希望避免不必要的内存分配。因此,重新使用向量的容量将是明智之举。

        e.g。

        std::vector<float> buf;
        while (thereIsMoreData())
        {
            createVectorFromArray(buf);   // option 3
            useTheData(buf);
            // data no longer needed, so we can re-use the vector
        }
        

        备选方案:

        while (thereIsMoreData())
        {
            // the passing of the vector is efficient, particularly as of c++11
            // however, we still suffer one memory allocation per loop.
            // probably undesirable in a high performance environment.
            useTheData(createVectorFromArray());   // option 2
        }
        

        ...最后

        选项4:

        提供两者。允许用户按照他/她的意愿使用高效方法或“可读”方法

        void createVectorFromArray(vector<float>& resVector)
        {
            //
            // if resVector has been used before and has a capacity() of 10
            // or more, no memory allocation necessary
            //
            resVector.resize(10);
        
            // one copy of data
            readDataFromSomewhere(std::addressof(resVector[0]), resVector.size());
        }
        
        // overload
        std::vector<float> createVectorFromArray()
        {
            std::vector<float> result;
            createVectorFromArray(result);
            return result;
        }
        

答案 2 :(得分:0)

int checkBoxWidth = foregroundHeight / 12.0; int checkBoxHeight = foregroundHeight / 12.0; UIButton* checkBox = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, checkBoxWidth, checkBoxHeight)]; //[checkBox setBackgroundImage:[Utility getEmptyCheckBoxOutIcon] forState:UIControlStateNormal]; //[checkBox setBackgroundImage:[Utility getCheckBoxOutIcon] forState:UIControlStateSelected]; [checkBox setImage:[Utility getEmptyCheckBoxOutIcon] forState:UIControlStateNormal]; [checkBox setImage:[Utility getCheckBoxOutIcon] forState:UIControlStateSelected]; checkBox.layer.borderWidth = 1.0; checkBox.layer.borderColor = [Utility primaryColor].CGColor; checkBox.layer.cornerRadius = cornerRadius; [switchView addSubview:checkBox]; 此处将std::vector::assign的内容复制到myArr,因此当resVector超出范围并返回myArr时,它就不会重要但仍将包含值。

更简单的方法是将resVector传递给myArr, myArr + 10构造函数,如下所示:

vector

正如另一个答案所说,你实际上可以像这样完全摆脱阵列:

float myArr[10];
readDataFromSomewhere(myArr, 10);
vector<float> resVector(myArr, myArr + 10);
return resVector;