c++ vector push说明

1 篇文章 0 订阅

我们在用动态内存分配时,经常是用new来定义一块内存空间,比如说 int* p = new int(1);这时会在堆上分配一块内存,当作int类型使用,内存中存储的值为1并将内存地址赋值给在栈中的int*类型的p,此时p本身也有一个内存地址,p的内容是一块地址,该地址指向1,相当于p与1关联。
当不使用p时,往往需要用delete p将其释放,我们需要注意的是释放一个指针p(delete p;)编译器只会释放该指针所指向的内存空间,而不会删除这个指针本身。实际意思是断开p与1的关联,释放了它所占的堆空间,而不是删除p本身(指针p本身并没有撤销,它自己仍然存在,该指针所占内存空间并未释放,指针p的真正释放是随着函数调用的结束而消失),释放堆空间后,p成了"野指针",*p成为了随机数,所以为了安全一般会在释放后置空(p=NULL)。

example:

vector<int*> pInt;
for (int i = 0; i < 10; i++)
{
	int *a = new int;
	*a = i;
	pInt.push_back(a);
}

vector.push_back是将地址放入,当然这样说也有些问题,应当是拷贝一份地址


同样的下面这样写也是错误的

for (int i = 0; i < 10; i++)
{
	pInt.push_back(&i); 
}

不能这么操作,因为 i 在这个循环中只有一个地址,那么push进去的所有值都指向这同一个地址,修改一个就会全部都一起变


vector<int*> pInt;
for (int i = 0; i < 10; i++)
{
	int *a = new int;
	*a = i;
	pInt.push_back(a);
	delete a;
}

这里不能 delete a; 因为delete删除的是a指向的地址上的变量,选择pInt的每个元素都指向了他们,删除了也将没了,只会变成随机数,就是所谓的悬空指针。


   vector<int*> pInt;	
   for (int i = 0; i < 10; i++)
{
	int a;
	a = i;
	pInt.push_back(&a);
}

这样做也是不行,这样的话跟直接把 i 给 pInt 中 push 进去是没有区别的,a在定义时候初始化为 i 也是一样的。但是为什么会这样呢?输出了一些信息之后发现,此时 a 和 i 的地址是不一样的,但是!a 每次的地址都是一样的,所以第二次循环定义一个 a 对他进行赋值操作时候先前push进去的 a 的也是会一起变得,因为是同一个地址。

所以现阶段我自己能想到的最好的办法是自己分配内存,然后用完了以后如果需要释放内存就先释放内存,然后让指针指向NULL,如果不需要,那块地址已经有别人接管了,那就让之前那个指针直接指向NULL就可以了。如下:

vector<int*> pInt;
for (int i = 0; i < 10; i++)
{
	int *a = new int;
	*a = i;
	pInt.push_back(a); 
	a = NULL;
}

通过这个例子还能看出一个事情,就是,vector他push_back时候并不是将a拿过来插进去了,而是新开辟了一个内存,把a的值赋给新开辟的内存,也就是pInt[0]。(毕竟vector它说白了是数组,并不是链表,所以他的内存地址是连续的,不可能把一个随随便便的a加进来,链表的话还能理解)
总结:vector的push有两种情况,若源数据在栈上创建,则拷贝值,若源数据在堆上创建,则拷贝其指向的地址

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值