- 注意,
int* pt;
中pt是int值的地址并不意味着pt本身的类型是int。例如,在有些平台中,int类型是个2字节值,而地址是个4字节值。
- 对于指针,需要指出的另一点是,new分配的内存块通常与常规变量声明分配的内存块不同。常规变量的值都存储在被称为栈(stack)的内存区域中,而new从被称为堆(heap)或自由存储区(free store)的内存区域分配内存。
- 在C++中,值为0的指针被称为空指针(null pointer)。C++确保空指针不会指向有效的数据,因此它常被用来表示运算符或函数失败(如果成功,它们将返回一个有用的指针)。
- 一定要配对地使用new和delete;否则将发生内存泄露(memory leak),也就是说,被分配的内存再也无法使用了。如果内存泄露严重,则程序将由于不断寻找更多内存而终止。
- 不要尝试释放已经释放的内存块,C++标准指出,这样做的结果将是不确定的,这意味着什么情况都可能发生。另外,不能使用delete来释放声明变量所获得的内存。
int* ps = new int; // ok
delete ps; // ok
delete ps; // not ok now
int jugs = 5; // ok
int* pi = &jugs; // ok
delete pi; // not allowed, memory not allocated by new
- 警告:只能用delete来释放使用new分配的内存。然而,对空指针使用delete是安全的。
- 注意,使用delete的关键在于,将它用于new分配的内存。这并不意味着要使用用于new 的指针,而是用于new的地址:
int* ps = new int; // allocate memory
int* pq = ps; // set second pointer to same block
delete pq; // delete with second pointer
一般来说,不要创建两个指向同一个内存块的指针,因为这将增加错误地删除同一个内存块两次的可能性。
- 总之,使用new和delete时,应遵守以下规则:
- 不要使用delete来释放不是new分配的内存;
- 不要使用delete释放同一个内存块两次;
- 如果使用new []为数组分配内存,则应使用delete []来释放;
- Use delete(no brackets)if you used new to allocate a single entity;
- 对空指针应用delete是安全的。
- 实际上,程序确实跟踪了分配的内存量,以便以后使用delete []运算符时能够正确地释放这些内存。但这种信息不是公用的,例如,不能使用sizeof运算符来确定动态分配的数组包含的字节数。
- 在很多情况下,可以相同的方式使用指针名和数组名。对于它们,可以使用数组方括号表示法,也可以使用解除引用运算符(*)。在多数表达式中,它们都表示地址。而数组名和指针之间的根本差别:不能修改数组名的值,而指针是变量,因此可以修改指针的值。
pointername = pointername + 1; // valid
arrayname = arrayname + 1; // not allowed
另一个区别是,对数组应用sizeof运算符得到的是数组的长度,这种情况下,C++不会将数组名解释为地址,而对指针应用sizeof得到的是指针的长度,即使指针指向的是一个数组。
- 将指针变量加1后,其增加的值等于指向的类型占用的字节数。
- 数组的地址:对数组取地址时,数组名也不会被解释为其地址。等等,数组名难道不被解释为数组的地址吗?不完全如此:数组名被解释为其第一个元素的地址,而对数组名应用地址运算符时,得到的是整个数组的地址:
short tell[10]; // tell an array of 20 bytes
cout << tell << endl; // displays &tesll[0]
cout << &tell << endl; // displays address of whole array
从数字上说,这两个地址相同;但从概念上说,&tell[0](即tell)是一个2字节内存块的地址,而&tell是一个20字节内存块的地址。因此,表达式tell + 1将地址值加2,而表达式&tell + 1将地址加20。换句话说,tell是一个short指针(* short),而&tell是一个这样的指针,即指向包含20个元素的short数组(short (*) [20])。
您可能会问,前面有关&tell的类型描述是如何来的呢?首先,您可以这样声明和初始化这种指针:
// pas points to array of 20 shorts
short (*pas)[20] = &tell;
如果省略括号,优先级规则将使得pas先与[20]结合,导致pas是一个short指针数组,它包含20个元素,因此括号是必不可少的。其次,如果要描述变量的类型,可将声明中的变量名删除。因此,pas的类型为short (*) [20]。另外,由于pas被设置为&tell,因此*pas与tell等价,所以(*pas) [0]为tell数组的第一个元素。
- 对指针解除引用意味着获得指针指向的值,另一种对指针解除引用的方法是使用数组表示法,例如,pn[0]与*pn是一样的。决不要对未被初始化为适当地址的指针解除引用。
- 在多数情况下,C++将数组名视为数组的第一个元素的地址。一种例外情况是,将sizeof运算符用于数组名用时,此时将返回整个数组的长度(单位为字节)。
- 还可以将一个指针减去另一个指针,获得两个指针的差。后一种运算将得到一个整数,仅当两个指针指向同一个数组(也可以指向超出结尾的一个位置)时,这种运算才有意义;这将得到两个元素的间隔。
扫码关注公众号,查看更多精彩内容
标签:C++,笔记,地址,007,内存,new,指针,tell,delete From: https://www.cnblogs.com/bobbycheng/p/18103028