C++ vector的push_back

来源:互联网 发布:动漫网站源码 编辑:程序博客网 时间:2024/06/01 09:58
1.1 函数声明:
void push_back ( const T& x );
1.2函数功能

Add element at the end

Adds a new element at the end of the vector, after its current last element. The content of this new element is initialized to a copy ofx.
This effectively increases the vector
size by one, which causes a reallocation of the internal allocated storage if the vector size was equal to the vectorcapacity before the call. Reallocations invalidate all previously obtained iterators, references and pointers.
大意:

1.在vector的最后一个元素后增加一个新元素,新元素师参数X的一个拷贝[换句话说,如果X是个对象,则会调用默认复制拷贝函数,即调用浅拷贝,这时候要特别注意对象内部的指针动态分配的内存]。

2调用此函数,会让vector的大小增加一个,但是在调用之前容器的大小(size)已经和容器的容量(cacpity)已经相等,此时的调用会导致vector内部重新分配内存[调用realloc].重新分配内存会先释放容器元素,也就是说之前的对象内的指针所指动态内存已经释放了.[这时候最容易产生错误!.因为是形参X的浅拷贝,vector内部在重新分配内存前,会先释放所占的动态内存。而传入的X对象的指针还是指向原来的内存,在将来[程序结束时或者实参x是局部对象],实参X[因为是引用,所以形参X也是实参]也会被释放,此时就会造成内存重复释放.

Parameters

x
Value to be copied to the new element.
T is the first template parameter (the type of the elements stored in the vector).

2.代码举例:

错误的代码:

int SFFailLogin::Initialize(){for (unsigned i = 0; i < redis_ips_.size(); i++) {RedisClient rc;redis_clients_.push_back(rc);redis_clients_[i].Initialize(redis_ips_[i], IConfig::instance()->getConfigInt("LIMIT_STORAGE", "PORT"),IConfig::instance()->getConfigInt("LIMIT_STORAGE", "DB"));}   return 0;}

此代码的前提是直接定义vector,并没有分配空间给verctor.即:vector<RedisClient>  redis_clients_;

潜在的错误:

    每次push_back后,都有可能造成vector内部的内存重新分配,即导致vector内存元素的内存释放,而传入的元素也会被释放,二次释放。

题外话:vector重新分配内存是如何进行的,可参考其他文章,大致是分配2^n的个容量.即分配1,2,4,8...


 

正确的代码:

int SFQreg::Initialize(){DEBUG_LOG("redis_ip_size is : %u", redis_ips_.size());for (unsigned i = 0; i < redis_ips_.size(); i++) {RedisClient rc;redis_clients_.push_back(rc);}for (unsigned i = 0; i < redis_ips_.size(); i++) {
redis_clients_[i].Initialize(redis_ips_[i], IConfig::instance()->getConfigInt("LIMIT_STORAGE", "PORT"),IConfig::instance()->getConfigInt("LIMIT_STORAGE", "DB"));}    return 0;}

此代码也欠妥,但是功能正确.

分成两个for循环,第一个for循环是将所有对象rc加入vector中,因为我没有对rc做任何操作,vector你随便扩容,即随便释放内存,因为我rc对象是空的。第二个for循环,是对容器中的rc对象进行处理,即对容器的rc分配动态内存。由于容器中的rc是 传入的空rc的一个拷贝,在函数结束后,空rc被释放,释放的空间已经和 容器中rc动态分配的 不是同一样东西了。

 

 

 

 

 

0 0