Chinaunix首页 | 论坛 | 博客
  • 博客访问: 710487
  • 博文数量: 214
  • 博客积分: 5015
  • 博客等级: 大校
  • 技术积分: 2285
  • 用 户 组: 普通用户
  • 注册时间: 2006-06-18 17:02
文章分类

全部博文(214)

文章存档

2008年(43)

2007年(171)

我的朋友

分类:

2008-04-21 11:15:59

三种形式的new表达式
<1>    单个对象的动态分配
<2>    数组的动态分配
<3>    定位new表达式
------------------------------------------------------------------
<1>
#define TR(S) cout << #S" : " << S << endl

int *pi = new int(11); // initializer
TR(*pi);
int i = 22;
int *q = new int;   //assign
*q = i;
TR(*q);

*    因为new表达式是从堆上申请内存,但堆上空闲储存区是有限的,但空闲储存区内存耗尽时,导致new表达式失败,抛出bad_alloc异常
*    常见new错误    <1> delete表达式失败(内存泄漏 memory leak)    <2>对同以内存用2次delete    <3>对象被释放后继续读写该对象
---------------------------------------------
auto_ptr (自动管理用new表达式动态分配的内存)
auto_ptr pi(new int(11));
cout << *pi << endl;
pi的作用域跟普通变量的作用域一样的,在pi的生命期结束时, 被释放
{
     auto_ptr pi(new int(11));
}
cout << *pi << endl;        // error C2065: 'pi' : undeclared identifier
------------------------------------------------------------------------
auto_ptr p1(new int(11));
auto_ptr p2(new int(22));
cout << *p1 << endl;
cout << *p2 << endl;
p1 = p2;
cout << *p1 << endl;
//cout << *p2 << endl;   // error   这样p2被重置为0
if (p2.get() == 0)                        //  
cout << "p2 is alive" << endl;
p2.reset(new int(33));               // 只能这样重置p2
cout << *p2 << endl;
----------------------------------------------------------------------
auto_ptr str1(new string("aaaaa"));
str1.reset(new string("bbbbbbbbb"));
cout << *str1 << endl;
str1->assign("ccccc");   //这样更有效...
cout << *str1 << endl;
需要包含头文件string 和memory 刚才一时情急忘了加#inlcude 然后居然把输出写成cout << str1 << endl;没有解引用...呵呵...- -!
* 用auto_ptr对象并不比直接使用指针代价高,大多操作都是inline的
*auto指针的是用指针的所有权方式,当把一个指针赋值给另一个指针的时候,后者拥有所有权,前者不再指向原来的对象,被赋值为0.
---------------------------------------------------------------------------
int *p = 0;
if ( !p )
   cout << "p is non-initialize" << endl;
auto_ptr p2;      // 从这里也能看出跟普通指针的不同, auto_ptr自动将对象初始化为0
if (!p2.get())
   cout << "p2 is non-initialize" << endl;
*使用普通指针是可以用是否为0,而auto_ptr不可以,auto_ptr用get()返回对象内部的底层指针(用reset()来重置一个底层指针),
----------------------------------------------------------
*    不能用一个指向"内存不是用new分配的"指针来初始化或者赋值auto_ptr指针
*    不能让两个auto_ptr对象拥有空闲存储区内同一对象的所有权()
 
2>数组的动态分配
int *pi = new int[11];   // 分配有11个元素的动态数组
int (*pia)[11] = new int [22][11];   //分配一个含有 22 * 11 个元素的二维数组
*    动态分配的数组不能给出初始化值,一般在 for 循环中一个一个的初始化
   eg:           for(int i = 0; i < 11; i++)
                  pi[i] = 0;
*    动态数组的第一维不必是常量值, 这样就不必在编译时刻就知道维数,我们可以根据需要分配大小合适的内存单元
*    释放动态数组:        delete [ ] pi;    如果不小心忘记了空括号,编译器不会捕捉到这个错误, 务必要小心
*     一般为了避免动态分配数组带来的内存管理的问题, 我们使用c++ 的 标准库vector, list or string 会自动管理内存的容器类型
---------------------
常量对象的动态分配
const int *pic = new const int(1024);
*     const 对象必须被初始化, 否则会编译错误,(因此我们也不能创建const数组,因为const数组不能被初始化,除了类数组)
*    用new表达式返回的值作为初始值的指针必须是一个指向const类型的指针. eg: const int
*    它的生命期同样也用delete表达式来结束 eg: delete pic;
=============================================================
<3>定位new表达式(placement new expression)
形式: new (place_address) type-specifier
头文件: #include
place_adress必须是指针
eg:
int *buf = new int[2];
int *pb = new (buf) int;
*pb = 11;
cout << *pb << endl;             // 11
cout << *buf << endl;            // 11
cout << pb << endl;                 // 同样pb跟buf的所指向的地址也是相同的
cout << buf << endl;                //

int *pp = new (buf + 1) int;
*pp = 22;
*    因为定位符并不分配内存,所以我们并没有与定位符相匹配的delete表达式, 对此我们需要删除的是分配内存的指针,在上面的例子中我们 delete [] buf;
阅读(2717) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~