From the archive
c++ pointer 学习笔记
I.pointer的概念: 一个包含了内存的地址的变量.
容易混淆的东西:
&VarA 和 pointer的区别: VarA不是pointer,只是一般的变量. &VarA是VarA的10进制内存地址的意思,不过&VarA不构成一个pointer,因为&VarA没有占用另外一个内存来放置内存地址信息.
*和&的区别: 一个pointer应该是一个变量,而且变量中包含了内存地址. & 和 * 只是操作符号. &和*互相为反操作。&意思为"查询这个变量的10进制地址",而*的意思为"查询10进制地址的内容"。我们假设VarPtr是一个pointer变量,VarInt是一个普通变量,那么 *VarPtr = VarInt 和 VarPtr=&VarInt 这两个操作都是合理且成立的。注意&VarInt=VarPtr是不成立的,想下为什么?
int * VarA — 意思为 VarA被指定为一个pointer,VarA内容是10进制的内存地址
& VarA — VarA为一般变量,这里意思为这个变量的10进制内存地址
int ( *VarA ) — VarA为一个pointer,内容为10进制的内存地址,这里吧这个pointer所指向的内存内容改变为int形式。
要点:
1. pointer也是有type的. int, float, struct 在内存中占用的大小不同,所以pointer指定的应该不单是内存地址,而且还有内存范围.
2. 一个class, stuct等type的组合数据,pointer访问其member的格式为: (*VarPtr).MemberFunction() 或者 VarPtr->MemberVar .
当使用’.’的时候,是"查询某内存地址的内容属下的member";当使用’->’的时候,是"查询某pointer属下的member pointer".(个人理解)
II.Dynamic Allocation of Memory Space 动态分配内存
New命令:
对于array, struct等集合相当有用.
new命令与集合型的变量群就像不知道具体人数的预定."我需要在5月3日预定餐桌,人数不知道".这样酒店可以在5月3日才分配餐桌,从而节省了双方的费用.
看如下例子
char * ptr; // line 1
ptr = new char; // line 2
*ptr = ‘B’; // line3
cout << *ptr; //line 4
After line 1:
memory
======
| |
|—–|
4000 | ??? | ptr
|—–|
| |
|—–|
| |
|—–|
| |
|—–|
| |
|—–|
| |
After line 2:
memory
======
| |
|—–|
4000 |5600 | ptr
|—–|
| |
|—–|
| |
|—–|
| |
|—–|
5600 | | // allocated space
|—–|
| |
After line 3:
memory
======
| |
|—–|
4000 |5600 | ptr
|—–|
| |
|—–|
| |
|—–|
| |
|—–|
5600 | ‘B’ | // allocated space
|—–|
| |
Line1可以省略而有相同效果
delete命令:
假如日子还没到,就如同预定后取消预定.假如是已经到日期并且入座了,就是结帐并取消预定.
delete命令只擦除了该指针指向的内容和该指针的指向,而指针本身还在,处于unsigned状态,这时候避免出错,应该把指针指向Null.
内存泄露 (memory leaking):
形象地说,还用酒店例子,就是在各种频繁的预定,取消预定,结帐动作后,产生一些处于预定状态,而其实并没有人会来的桌子.
例如,A客户说,我要一个10人桌.然后B客户也来了,说我要一个20人桌.然后A客户后来突然说,B客户的20人桌子是帮我预定的,我们要坐一起.于是,当初A客户预定的10人桌就被遗忘在角落里了,被浪费掉了.
正确的步骤是,酒店经理应当先取消掉A客户预定的10人桌,然后把A客户指定到B客户预定的桌子上.
就是说,每次重新指向指针的时候,都要用delete操作取消原来指针的内存预定和被预定的内存块,避免浪费.
空指针 (dangling pointer):
就是一个无效的预定.如同一个客人以为自己预定了个桌子,来到后却发现酒店没有为他预留位置.
所有空指针我们都要给予一个Null指向来提醒这是一个无内容的预定.