C++ Primer第五版笔记——动态数组

new和数组

. 为了让new分配一个对象数组,需要在类型名后跟方括号,括号中是分配对象的数目,该数目必须是整型,但不必是常量;
  new T[] 分配的内存并不是得到一个数组,而是得到一个数组元素类型的指针,因此不能对动态数组调用begin和end;
  与普通数组不同的是,普通数组不能定义长度为0的数组,但是使用new时却能在后面的中括号中使用0:int* p = new int[0],这里返回一个合法的非空指针,
该指针可以作比较操作,但是不能解引用,因为它不指向任何元素。

初始化

默认情况下,new分配的对象是默认初始化的;
  可以对数组中的元素进行值初始化,方法是在大小之后加一个空括号:**int p = new int10***;
  在新标准中,可以通过花括号进行列表初始化:**int p = new int[5]{0,1,2,3,4}***,如果列表中的数目小于分配数目,剩余部分进行值初始化,如果列表中的数目大于分配数目,语句执行失败。

释放动态数组:

. 为了释放动态树组,使用一种特殊形式的delete,在delete和指针中间加上一个中括号:delete [] p,该语句首先销毁p所指向的数组中的最后一个元素,然后逆序进行销毁;
  当我们释放一个指向数组的指针时,空方括号是必需的:它指示编译器此指针指向一个对象数组的第一个元素,当我们delete一个对象数组时忽略了方括号,
  或者在delete一个单一对象的时候使用了方括号,编译器或许不会给出警告,但是其行为都是未定义的。

智能指针和动态数组:

标准库提供了一个可以管理new分配的数组的unique_ptr版本。使用方式如下:

	//p指向一个包含10个未初始化int的数组
	unique_ptr<int[]> p(new int[10]);
	up.release();					//自动用delete[]销毁指针
上面的代码中p所指向的类型是一个int数组,因此不能使用点运算符和箭头运算符,与此同时可以使用下标运算符来访问数组中的元素。

allocator类

new有一些灵活性上的局限,其中一方面表现在它将对象的内存分配和对象构造组合在一起,类似的delete将对象的内存释放和对象的析构函数组合在一起,比如:
  string const p = new string[100],但我们可能永远用不到第100个string*,当分配一大块内存时,通常计划在这块内存上按需构造对象,在这种情况下,则希望能将内存分配和对象构造分离开来,这意味着可以分配大块内存,但是只在真正需要的时候执行对象创建操作。

allocator类:

. 标准库allocator类定义在头文件memory中,类似vector,它是一个模板。当一个allocator对象分配内存时,它会根据给定的对象类型来确定恰当的内存大小和对齐位置,其分配的内存是原始的、未被构造的内存:

		allocator<string> allc;				//可以分配string的allocator对象
		auto const p = allc.allocate(n);	//分配n个未初始化的string

其算法如下:
这里写图片描述

allocator构造:

. 可以按需要在allocator分配的原始内存中构造对象,这样才能正常使用,使用未被构造的内存,行为将是未定义的。
  使用construct成员函数来初始化构造对象:

		auto q = p;
		allc.construct(q++);				//*q为空字符串
		allc.construct(q++,10,'c');			//*q为cccccccccc
		allc.construct(q++,"asdf");			//*q为asdf

. 当我们用完对象后,需要对每个构造的元素调用destroy来销毁它们,也只能对真正构造的元素调用destroy函数,destroy接受一个指针,对指向的对象调用析构函数:

		while(q != p){
			allc.destory(--q);
		}

. 当元素被销毁后,可以重新使用这部分内存保存其他的string,也可以将其还给系统,释放内存通过deallocate来完成:
  allc.deallocate(p,n);
  传递给deallocate的指针不能为空,必须指向allocate分配的内存,且n的值与其相同。

拷贝与填充算法:

标准库为allocator定义了两个伴随算法,用于在未分配的内存中创建对象:
这里写图片描述

		auto p = allc.allocate(v.size() * 2);				//分配一块比v所占用内存
		auto q = uninitialized_copy(v.begin(),v.end(),p)	//将v中的元素拷贝到p所指向内存的前一半,返回值是一个指向最后一个构造的元素之后位置的指针
		uninitialized_fill_n(q,v.size(),42);				//将剩余元素初始化为42
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值