首页 > 编程语言 >C++学习笔记——007

C++学习笔记——007

时间:2024-03-29 09:24:48浏览次数:29  
标签:C++ 笔记 地址 007 内存 new 指针 tell delete

  • 注意, 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

相关文章

  • C++学习笔记——006
    事实上,任何两个由空白(空格、制表符和换行符)分隔的字符串常量都将自动拼接成一个。因此,下面所有的输出语句都是等效的:cout<<"I'dgivemyrightarmtobe""agreatviolinist.\n";cout<<"I'dgivemyrightarmtobeagreatviolinist.\n";cout<<&qu......
  • stm32f103c8t6学习笔记(学习B站up江科大自化协)-DMA
    DMA简介    ·DMA主要用于协助CPU完成数据转运的工作    ·DMA,英文全称DirectMemoryAccess,DMA这个外设是可以直接访问STM32内部存储器的,包括运行内存SRAM,程序存储器flash和寄存器等等,DMA都有权限访问,所以DMA能完成数据转运的工作    ·第二行的外......
  • 面试题知识点笔记-MySQL开发
    目录可以使用MySQL直接存储文件(ppt,exel,图像等)吗?什么时候存,什么时候不存?Emoji乱码怎么办?存储的时候有遇到过什么问题吗?如何存储ip地址?长文本如何存储?大段文本如何设计表结构?大段文本查找时如何建立索引?有没有在开发中使用过TEXT,BLOB数据类型日期,时间如何存......
  • 面试题知识点笔记-MySQL日志
    目录MysqI会产生几种日志?binlog作用是什么?redolog作用是什么?undolog作用是什么?Mysql日志是否实时写入磁盘?binlog刷盘机制是如何实现的?redolog刷盘机制是如何实现的?undolog刷盘机制是如何实现的?MySQL的binlog有有几种录入格式?分别有什么区别?Mysq!集群同......
  • lanqiao106. 正则问题 (第八届蓝桥杯C++A组)或者 acwing 1225. 正则问题
    问题:知识补充:1. 正则表达式的计算①括号代表优先计算,②或符号代表二选一。比如给的例子:((xx|xxx)x|(x|xx))xx 2. 字符串的语法问题:string是字符串的类型,使用的时候也使像字符一样使用,加入定义stringstr,那么使用的时候要写成str[]思考:妈呀一开始我不会算正则表达......
  • C++取经之路(其二)——含数重载,引用。
    含数重载:函数重载是指:在c++中,在同一作用域,函数名相同,形参列表不相同(参数个数,或类型,或顺序)不同,C语言不支持。举几个例子:1.参数类型不同intAdd(intleft,intright){ cout<<"intAdd(intleft,intright)"<<endl; returnleft+right;}doubleAdd(doublele......
  • 论文笔记 SimpleNet A Simple Network for Image Anomaly Detection and Localization
    背景对于工业场景上的异常检测和定位任务,由于零件的异常情况具有多样性和随机性,所以很难用有监督的方式来解决;目前用的最多的是用无监督的方式,在训练过程中只使用正常样本进行训练,目前无监督解决异常检测任务的三个趋势是基于重建的方法,基于合成的方法以及基于嵌入的......
  • 树哈希学习笔记
    1.作用判断一些树是否同构。2.方法2.1.具体操作这类方法需要一个多重集的哈希函数。以某个结点为根的子树的哈希值,就是以它的所有儿子为根的子树的哈希值构成的多重集的哈希值,即:\[h_u=f(\{h_v|v\inson(u)\})\]其中\(h_x\)表示以\(x\)为根的子树的哈希值,\(f\)是多重集的......
  • 3.28 第一次结对笔记
     今天准备设计一下地铁查询系统的整体架构,因为北京地铁的线路繁多,所以在设计数据库表时就存在很大问题,如何设计才能在存储数据时以及前后端处理数据时,都简便一些。当然如果一方面过度的方便就证明另一方面极其困难,在博客园找到了15年地铁站点的数据,但是对比现在差的太多了,所以我......
  • 新手c语言笔记
    第1章认识C语言C语言是国际流行的使用最广泛的感激程序设计语言。它既可以用来写系统软件,也可以用来写应用软件。1.1C语言的特点(1)c语言简洁紧凑,编写的程序短小精悍。(2)运算符丰富,数据结构丰富。c语言程序生成代码的质量较高,程序执行效率高。(3)C语言限制不太严格,程序设计自......