如何在不循环的情况下将数组的内容复制到 C + + 中的 std: : Vector?

我有一个值数组,它从程序的不同部分传递给我的函数,我需要为以后的处理存储这些值。因为我不知道在处理数据之前我的函数会被调用多少次,所以我需要一个动态存储结构,所以我选择了 std::vector。我不想做的标准循环到 push_back所有的值个别,这将是很好的,如果我可以只是复制它所有使用类似于 memcpy的东西。

233903 次浏览

Copy 就是你要找的。

因为我只能编辑我自己的答案,所以我要根据我问题的其他答案做一个综合答案。感谢所有接电话的人。

使用 收到,这仍然在后台迭代,但是您不必键入代码。

int foo(int* data, int size)
{
static std::vector<int> my_data; //normally a class variable
std::copy(data, data + size, std::back_inserter(my_data));
return 0;
}

使用常规 Memcpy。这可能最适用于基本数据类型(即 int) ,但不适用于更复杂的结构或类数组。

vector<int> x(size);
memcpy(&x[0], source, size*sizeof(int));

假设你知道向量中的项有多大:

std::vector<int> myArray;
myArray.resize (item_count, 0);
memcpy (&myArray.front(), source, item_count * sizeof(int));

Http://www.cppreference.com/wiki/stl/vector/start

要我说,避开那些杂乱无章的东西。没有理由干扰指针操作,除非您真的必须这样做。此外,它将只适用于 POD 类型(如 int) ,但是如果您处理的类型需要构造,那么它将失败。

除了上面提到的方法之外,您还需要确保使用 std: : Vector.reserve ()、 std: : Vector.resize ()或者构造一个大小相同的向量,以确保向量中有足够的元素来保存数据。否则,你会破坏记忆。对于 std: : copy ()或 memcpy ()都是如此。

这就是使用 vector.push _ back ()的原因,您不能写超过向量的末尾。

如果你能在得到数组和数组大小之后构造向量,你可以说:

std::vector<ValueType> vec(a, a + n);

... 假设 a是你的数组,而 n是它包含的元素数。否则,std::copy() w/resize()就会起作用。

我会远离 memcpy(),除非您可以确定这些值是普通的旧数据(POD)类型。

另外,值得注意的是,这些都没有真正避免 for 循环——这只是一个问题,您是否必须在代码中看到它。对于复制值,O (n)运行时性能是不可避免的。

最后,请注意,C 样式的数组对于大多数 STL 算法来说都是完全有效的容器——原始指针等价于 begin(),(ptr + n)等价于 end()

如果您所做的只是替换现有的数据,那么您可以这样做

std::vector<int> data; // evil global :)


void CopyData(int *newData, size_t count)
{
data.assign(newData, newData + count);
}

还有一个答案,因为这个人说“我不知道我的函数会被调用多少次”,你可以像这样使用向量插入方法来在向量的末尾附加值的数组:

vector<int> x;


void AddValues(int* values, size_t size)
{
x.insert(x.end(), values, values+size);
}

我喜欢这种方式,因为向量的实现应该能够优化插入基于迭代器类型和类型本身的值的最佳方式。您在某种程度上是在回答 stl 的实现问题。

如果你需要保证最快的速度,并且你知道你的类型是 POD 类型,那么我会推荐 Thomas 的答案中的 resize 方法:

vector<int> x;


void AddValues(int* values, size_t size)
{
size_t old_size(x.size());
x.resize(old_size + size, 0);
memcpy(&x[old_size], values, size * sizeof(int));
}

这里有很多答案,几乎所有的答案都能解决问题。

然而,有一些误导性的建议!

下面是一些选择:

vector<int> dataVec;


int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
unsigned dataArraySize = sizeof(dataArray) / sizeof(int);


// Method 1: Copy the array to the vector using back_inserter.
{
copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}


// Method 2: Same as 1 but pre-extend the vector by the size of the array using reserve
{
dataVec.reserve(dataVec.size() + dataArraySize);
copy(&dataArray[0], &dataArray[dataArraySize], back_inserter(dataVec));
}


// Method 3: Memcpy
{
dataVec.resize(dataVec.size() + dataArraySize);
memcpy(&dataVec[dataVec.size() - dataArraySize], &dataArray[0], dataArraySize * sizeof(int));
}


// Method 4: vector::insert
{
dataVec.insert(dataVec.end(), &dataArray[0], &dataArray[dataArraySize]);
}


// Method 5: vector + vector
{
vector<int> dataVec2(&dataArray[0], &dataArray[dataArraySize]);
dataVec.insert(dataVec.end(), dataVec2.begin(), dataVec2.end());
}

长话短说方法4,使用 Vector: : insert,是 bsruth 场景的最佳选择。

以下是一些血淋淋的细节:

方法1 可能是最容易理解的。只要从数组中复制每个元素并将其推到向量的后面。唉,太慢了。因为存在一个循环(通过复制函数隐含) ,所以必须单独处理每个元素; 基于我们知道数组和向量是连续的块这一事实,不能对性能进行任何改进。

方法2 是对方法1的建议性能改进; 只需在添加数组之前预先保留数组的大小。对于大型数组,这个 也许吧有所帮助。然而,这里最好的建议是永远不要使用 reserve,除非分析表明您可以得到改进(或者您需要确保迭代器不会失效)。比昂同意.顺便说一下,我发现这种方法执行 最慢的的大部分时间,虽然我正在努力全面解释为什么它经常 意义重大慢于方法1..。

方法3 是老派的解决方案-在问题上投入一些 C!适用于 POD 类型。在这种情况下,需要调整大小,因为 memcpy 的工作范围超出了向量的界限,而且没有办法告诉向量它的大小已经改变。除了是一个丑陋的解决方案(字节复制!)请记住,这可以 只能用于 POD 类型。我绝不会用这种方法。

方法4是最好的方法。它的意思是清楚的,它(通常)是最快的,它适用于任何物体。对此应用程序使用此方法没有不利之处。

方法5 是方法4上的一个调整——将数组复制到一个向量中,然后附加它。不错的选择——通常是快速而清晰的。

最后,您知道您可以使用向量代替数组,对吗?即使一个函数需要 c 样式的数组,你也可以使用向量:

vector<char> v(50); // Ensure there's enough space
strcpy(&v[0], "prefer vectors to c arrays");

希望能帮到别人!

int dataArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//source


unsigned dataArraySize = sizeof(dataArray) / sizeof(int);


std::vector<int> myvector (dataArraySize );//target


std::copy ( myints, myints+dataArraySize , myvector.begin() );


//myvector now has 1,2,3,...10 :-)