Code Bye

如何把一个vector赋值给另一个vector

刚刚开始写C++程序,现在遇到了这个问题。目前只看了C++ Primer 第五版的前几章,里面详细说了vector的初始化,以及迭代器,但是并没有详细说明怎么赋值。百度搜索了一些帖子,发现有以下几种方法:
1:迭代器赋值,这个我知道,但是缺点是要用 for 循环,代码不够简洁
2:vector<double> p2(4, 0.0);
      vector<double> p4(4, 1.0);
      p2 = p4;
这个是我目前用的,但是奇怪的是在运行程序的时候,有时候没问题,有时候会出现下面的问题,我就傻了。。。
(gdb) s
694                                     p2 = p4;    //  Radiated gluon from colljet23
(gdb) p p2
$4 = std::vector of length 4, capacity 4 = {2.847704044428288, 0.08712303953697198, 1.3861864765274348, 2.4860239244479372}
(gdb) p p4
$5 = std::vector of length 4, capacity 4 = {16.121628775001703, 0.72265308163598341, -2.5018098411777703, 15.909922513989532}
(gdb) s
std::vector<double, std::allocator<double> >::operator= (this=0x7fffffffb8e0, __x=std::vector of length 4, capacity 4 = {…}) at /usr/include/c++/4.9/bits/vector.tcc:170
170       if (&__x != this)

3:p2.assign(p4.begin(), p4.end());
这个方法我没用过。

4: copy
也没有用过

我之前学过C语言基础,现在在使用一个程序,里面用的数组,好几个数组的初始化是4*2000000,数据个数是未知的,其实并没有那么多。程序运行完得花1分钟,但是我们需要用蒙特卡洛方法运行1000000次类似的过程,花的时间太长。我怀疑程序占用太过内存导致运行时间太长,就打算把里面的数组改成vector,新的数据用vector.push_back()添加,每运行一个过程后就vector.clear(),应该可以减少所需内存

5分
c++自动用=号就行了啊。。或者函数的话用引用传递
10分
非也,在内存足够的情况下,使用数组的速度要高于vector,数组是连续的内存,而vector要不定期的申请、释放内存,在数据量大时,效率反而比较低。如果对数组元素有查询的需求,那则另当别论。
1000000次计算本身就耗时较多,如果单次运算算法不够优化,那计算耗时是肯定的。
还有一种可能,计算所用计算机内存较低,发生了内存交换,导致耗时较长,不过现如今内存普遍比较便宜,这个可能较小。
引用 1 楼 FightForProgrammer 的回复:

c++自动用=号就行了啊。。或者函数的话用引用传递

是啊,我现在也是用的 = 号, 可是你看我的调试信息,程序运行到这里出现问题了。。

引用 2 楼 cjqpker 的回复:

非也,在内存足够的情况下,使用数组的速度要高于vector,数组是连续的内存,而vector要不定期的申请、释放内存,在数据量大时,效率反而比较低。如果对数组元素有查询的需求,那则另当别论。
1000000次计算本身就耗时较多,如果单次运算算法不够优化,那计算耗时是肯定的。
还有一种可能,计算所用计算机内存较低,发生了内存交换,导致耗时较长,不过现如今内存普遍比较便宜,这个可能较小。

我不知道这个程序得花多少内存,程序是在一个公共的64位linux服务器上运行的,总共有60多G的内存。这个程序需要存储的变量大概在5000个,具体大小只有等程序运行完了才知道。我以为C++里面的vector比数组高级,效率也会更高呢。如果数组的效率更高,那我只能把数组的2000000改成20000试试

引用 3 楼 wseektime 的回复:
Quote: 引用 1 楼 FightForProgrammer 的回复:

c++自动用=号就行了啊。。或者函数的话用引用传递

是啊,我现在也是用的 = 号, 可是你看我的调试信息,程序运行到这里出现问题了。。

对不起,弄错了,我贴出来的不是错误发生的地方,是调试的时候进入了头文件,我以为是在这个点出错了

5分
用swap试试
5分
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> foo (3,100);   // three ints with a value of 100
  std::vector<int> bar (5,200);   // five ints with a value of 200

  foo.swap(bar);

  std::cout << "foo contains:";
  for (unsigned i=0; i<foo.size(); i++)
    std::cout << "" "" << foo[i];
  std::cout << ""\n"";

  std::cout << "bar contains:";
  for (unsigned i=0; i<bar.size(); i++)
    std::cout << "" "" << bar[i];
  std::cout << ""\n"";

  return 0;
}
引用 6 楼 yshuise 的回复:

用swap试试

swap是交换两个对象,可是我只想给一个对象赋值,另一个需要保持不变

引用 7 楼 yshuise 的回复:
#include <iostream>
#include <vector>

int main ()
{
  std::vector<int> foo (3,100);   // three ints with a value of 100
  std::vector<int> bar (5,200);   // five ints with a value of 200

  foo.swap(bar);

  std::cout << "foo contains:";
  for (unsigned i=0; i<foo.size(); i++)
    std::cout << "" "" << foo[i];
  std::cout << ""\n"";

  std::cout << "bar contains:";
  for (unsigned i=0; i<bar.size(); i++)
    std::cout << "" "" << bar[i];
  std::cout << ""\n"";

  return 0;
}

多谢你的实例,有木有更方便的 赋值

5分
=运算符重载,或者p2.assign(p4.begin(), p4.end());
参看:http://www.cplusplus.me/1112.html
引用 12 楼 paschen 的回复:

参看:http://www.cplusplus.me/1112.html

这上面写的我都知道,跟书上讲的没多少差别,而且也都是讲的初始化

引用 11 楼 OExpress 的回复:

=运算符重载,或者p2.assign(p4.begin(), p4.end());

恩,这个可以,我也会

好吧,事实是我把 gdb 调试进入了头文件的输出当成了 输出错误,因为 有时候这种输出太长了。。。

后来我调试的结果是 程序自己释放内存使用 free() 出错,可能是我使用vector 内存越界了,当我在vector使用前预先申请内存后,就没有这种报错了,可是我还是不知道程序自己在哪里 free()出错了。。。。
我昨天又重开了一个讨论。
http://bbs.csdn.net/topics/391042385?page=1#post-399258690
有兴趣的欢迎帮忙分析分析

10分
进入gdb然后使用bt命令
可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。
引用 16 楼 zhao4zhong1 的回复:

进入gdb然后使用bt命令
可以查看进程意外退出前函数调用的堆栈,内容为从上到下列出对应从里层到外层的函数调用历史。

我试了,还是那个错误。
源码:
    if (KATT.size() == KATT.capacity())
    {
    cout << “break = ” << ” ” << 2.22222 << endl;
        KATT.reserve(KATT.capacity() * 2);
    cout << “KATT.capacity() = ” << ” ” << KATT.capacity() << endl;
    }

                    KATT.push_back(KATT2);

输出:
break =  2.22222
*** Error in `./a.out””: double free or corruption (!prev): 0x0000000002af9a40 ***
Aborted (core dumped)
yayun@Hyy:~/Research/LBT_C++$ gdb a.out 
GNU gdb (Ubuntu 7.9-1ubuntu1) 7.9
Copyright (C) 2015 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type “show copying”
and “show warranty” for details.
This GDB was configured as “x86_64-linux-gnu”.
Type “show configuration” for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type “help”.
Type “apropos word” to search for commands related to “word”…
Reading symbols from a.out…done.
(gdb) bt
No stack.
(gdb) 

奇怪,为何没有。。。还有别的方法吗?

5分
引用或者指针来减少赋值带来的巨大开销!

还有你可以先预测你数据量,使用resize先分配一次空间

引用 19 楼 jianwen0529 的回复:

引用或者指针来减少赋值带来的巨大开销!

还有你可以先预测你数据量,使用resize先分配一次空间

现在不纠结赋值的问题了。现在我想确定程序报错的真正原因,请看16和17楼。

50分
2. 设置观察点(WatchPoint)
观察点一般用来观察某个表达式(变量也是一种表达式)的值是否变化了。如果有变化,马上停住程序。有下面的几种方法来设置观察点:
watch <expr>
为表达式(变量)expr设置一个观察点。一旦表达式值有变化时,马上停住程序。
rwatch <expr>
当表达式(变量)expr被读时,停住程序。
awatch <expr>
当表达式(变量)的值被读或被写时,停住程序。
info watchpoints
列出当前设置的所有观察点。
引用 21 楼 zhao4zhong1 的回复:

2. 设置观察点(WatchPoint)
观察点一般用来观察某个表达式(变量也是一种表达式)的值是否变化了。如果有变化,马上停住程序。有下面的几种方法来设置观察点:
watch <expr>
为表达式(变量)expr设置一个观察点。一旦表达式值有变化时,马上停住程序。
rwatch <expr>
当表达式(变量)expr被读时,停住程序。
awatch <expr>
当表达式(变量)的值被读或被写时,停住程序。
info watchpoints
列出当前设置的所有观察点。

对,找到错误了,有两个地方。
1:vector<int> KATT 是全局变量,可是我在另一个子函数里定义了一个同名的int,这可能不会导致free出错
2:在程序中我还定义了一个 vector<int> KATT0;有个地方把KATT写成了KATT0, 导致后来程序读KATT最后一个对象时越界了,应该就是这里。
果然还是犯的愚蠢错误。。。

5分
*** Error in `./a.out””: double free or corruption (!prev): 0x0000000002af9a40 ***

很明显的错误 ,同一个内存free了两次

KATT.push_back(KATT2);
这是什么?!你直接push一个vector<XXX>类型的数据吗?

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明如何把一个vector赋值给另一个vector