指针变量

c++中各类型数据所占字节数(二)

这一生的挚爱 提交于 2020-03-09 10:45:59
转自: https://blog.csdn.net/allen_tony/article/details/76973906 https://blog.csdn.net/zzwdkxx/article/details/53635173 关于多个父类,虚继承,类本身自己的虚函数,情况比较复杂,后续时间再研究。 类所占内存的大小是由成员变量(静态变量除外)决定的,成员函数是不计算在内的。摘抄部分: 成员函数还是以一般的函数一样的存在。a.fun()是通过fun(a.this)来调用的。所谓成员函数只是在名义上是类里的。其实成员函数的大小不在类的对象里面,同一个类的多个对象共享函数代码。而我们访问成员函数是通过类里面的一个指针实现,而这个指针指向的是一个table,table里面记录的各个成员函数的地址(当然不同的编译可能略有不同的实现)。所以我们访问成员函数是间接获得地址的。所以这样也就增加了一定的时间开销,这也就是为什么我们提倡把一些简短的,调用频率高的函数声明为inline形式(内联函数)。 如果类定义了虚函数,该类及其派生类就要生成一张虚拟函数表,即vtable。而在类的对象地址空间中存储一个该虚表的入口,占4个字节,这个入口地址是在构造对象时由编译器写入的。 所以,由于对象的内存空间包含了虚表入口,编译器能够由这个入口找到恰当的虚函数,这个函数的地址不再由数据类型决定了。

「转」浅谈多态机制的意义及实现

别等时光非礼了梦想. 提交于 2020-03-09 09:56:34
转载来自: https://hesey.wang/2010/12/significance-and-implementation-of-polymorphism.html,感谢分享 什么是多态机制? 是父类或接口定义的引用变量可以 指向子类或实现类的实例对象 ,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实现对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。 浅谈多态机制的意义及实现 在面向对象编程(Object-Oriented Programming, OOP)中,多态机制无疑是其最具特色的功能,甚至可以说,不运用多态的编程不能称之为OOP。这也是为什么有人说,使用面向对象语言的编程和面向对象的编程是两码事。 多态并没有一个严格的定义,维基百科上给它下的定义比较宽松: Subtype polymorphism, almost universally called just polymorphism in the context of object-oriented programming, is the ability of one type, A, to appear as and be used like another type, B. 一、子类型和子类 这里我想先提一下 子类型(Subtype) 这个词和 子类

安卓开发过程中空指针的问题Java.lang.NullPointerException

依然范特西╮ 提交于 2020-03-09 07:44:14
最近做一个新闻客户端的应用,经常出现空指针的问题,我想一方面可能是自己水平有限,二是开发过程中有一些遗漏的地方。一般情况下新手出现空指针的概率较高。下面来总结一下经常出现的问题。 1.所谓的指针,就是java中的对象的引用。比如String s;这个s就是指针。 2.所谓的空指针,就是指针的内容为空,比如上面的s,如果令它指向null,就是空指针。 3.所谓的空指针异常,就是一个指针是空指针,你还要去操作它,既然它指向的是空对象,它就不能使用这个对象的方法。比如上面的s假如为null,你还要用s的方法,比如s.equals( String x);那么就会产生空指针异常。 原因: 1字符串变量未初始化; 2接口类型的对象没有用具体的类初始化,比如: List lt;会报错 List lt = new ArrayList();则不会报错了 3当一个对象的值为空时,你没有判断为空的情况。你可以试着把下面的代码前加一行代码: if(rb!=null && rb!="") 改成: if(rb==null); if(rb!==null&&rb!="") 或者if((“”).equals(rb)) 解决办法: 代码段1: out.println(request.getParameter("username")); 分析:代码段1的功能十分简单,就是输出用户输入"username"的值。 说明

你必须知道的指针基础-4.sizeof计算数组长度与strcpy的安全性问题

独自空忆成欢 提交于 2020-03-09 07:23:36
一、使用sizeof计算数组长度 1.1 sizeof的基本使用   如果在作用域内,变量以数组形式声明,则可以使用sizeof求数组大小,下面一段代码展示了如何使用sizeof: int nums[] = {11,22,33,44,55,66}; int i; // sizeof(nums) 计算nums数组的总字节数 // sizeof(int) 计算int类型所占用的字节数 int length = sizeof(nums)/sizeof(int); for(i=0;i<length;i++) { printf("%d ",nums[i]); }   其中sizeof(nums)代表计算nums数组的总字节数,而sizeof(int)则代表计算int类型所占用的字节数(32位系统下是4个字节,64位下可能不同,因此这里使用sizeof(int)可以向程序员屏蔽这个差异),运行结果为: 1.2 sizeof只能在编译时计算   假如我们将上面的代码做一个抽象,将数组的遍历及打印封装为一个方法,代码如下: void printEach(int* nums) { // sizeof(nums)在这里是计算指针的字节数 int length = sizeof(nums)/sizeof(int); printf("The length of nums is %d\n",length);

c语言指针详解

雨燕双飞 提交于 2020-03-09 06:47:55
c语言指针 1.指针是什么? 在c语言中指针和其他变量没有区别,例如 int a 和 int * b,我们可以看做为变量a 与变量b,只是 a存储的是整数值,而b存储的是整数变量的地址!!划重点地址!!! 2.指针的运算 int*a ,float*b,char *c,double*d a++ ,b++,c++, d++, 有什么区别? 已知 int 4字节 float 4个字节 char1个字节 double 8个字节 因为他们占据这些字节,而这些字节体现到内存上, 所以指针 a++ 偏移为4 ,float++偏移 4…依次类推 通过以上的结果我们可以归纳出 ​ 内存的存储长度与内存里面所存储的类型有关!!!划重点 3.指针与一维数组二维数组多维数组 一维数组与指针 int a[9] = {1,2,3,4,5,6,7,8,9}; ①a是什么? a是数组首元素的地址,意思在这个数组中 a代表 首元素1所在的地址 ②a的类型是什么? 因为a是首元素的地址,首元素为int类型,那么a为int *类型 ③a++的含义是什么?有什么用? a++代表往后移动四个字节,至于为啥四个字节呢 因为a是一个地址它存储的是int类型,所以在偏移四个字节后可以访问到a[1] 具体的用处可以用a++,访问数组中的值,可以用a[0] 中括号的方式访问到数组的值 ④写个程序来证明上方是对的 #include

算法解析:通过快慢指针判断链表是否存在环并找到环的起点

梦想与她 提交于 2020-03-09 06:17:11
问题描述 给定一个单向链表,请判断该链表是否存在环;如果存在的话,请找到环的起点。 重要 注1:为了描述方便,后文中除非特殊指定,否则将“ 单向链表 ”简称为“ 链表 ” 注2:本文以包含头结点的链表为例,如果是一个不含头结点的链表,因为起始位置不同,所以一些变量的定义会受到影响,但不影响本文讨论的解题方法 问题分析 一般情况下,一个链表存在一个 尾结点 ,该结点的 next 指针为空。然而,当一个链表的 尾结点 指向了之前的某个前序结点时,链表就出现了“ 环 ”: 本题就是要判断一个给定的链表是否存在环,并找到环开始的位置。 注:严格来说,有环链表是没有尾结点的,因为不存在“ 最后一个结点 ”。但后文为了描述方便,仍然将指向环首结点的这个结点称为 尾结点 。 解题方案 可以通过 快慢指针 来判断一个链表是否有环。 什么是快慢指针 在一个链表的头结点处设置两个指针 slow 和 fast 并同时向前移动,规定 slow 每次移动一个结点, fast 每次移动两个结点,这就是快慢指针。 如何利用快慢指针判断链表存在环 如果链表不存在环,则肯定存在一个结点,其 next 指针为空,所以,只要 fast 在移动过程中遇到了空结点,则证明链表不存在环。 如果链表存在环,那么,因为 fast 移动速度比 slow 要快,所以,一定会在某些时刻, fast 会从后面追上 slow 。问题在于:

【JVM.1】java内存区域与内存溢出

你离开我真会死。 提交于 2020-03-09 05:48:09
鲁迅曾说过:Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外面的人想进来,墙里面的人想出去。 一.虚拟机内存分布 Java虚拟机在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域。 1.  程序计数器(Program Counter Register)   程序计数器是一块较小的内存空间,它可以看作是当前线程所执行的 字节码的行号指示器 。    由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储。称之为“线程私有”的内存。程序计数器内存区域是虚拟机中唯一没有规定OutOfMemoryError情况的区域。 2.  Java虚拟机栈(Java Virtual Machine Stacks)   java虚拟机也是 线程私有 的,它的生命周期和线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储 局部变量表、操作数栈、动态链接、方法出口 等信息。   咱们常说的堆内存、栈内存中,栈内存指的就是虚拟机栈。 局部变量表存 放了编译期可知的各种 基本数据类型 (8个基本数据类型)、 对象引用

JVM运行时数据区域

三世轮回 提交于 2020-03-09 05:17:22
一、运行时数据区域 相应脑图 程序计数器 记录正在执行的虚拟机字节码指令的地址(如果正在执行的是本地方法则为空)。 Java 虚拟机栈 每个 Java 方法在执行的同时会创建一个 栈帧 用于 存储局部变量表 、 操作数栈 、 常量池引用等信息 。 从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。 对于执行引擎来说,活动线程中,只有栈顶的栈帧是有效的,称为 当前栈帧 ,这个栈帧所关联的方法称为 当前方法 。 执行引擎所运行的所有字节码指令都只针对当前栈帧进行操作。 操作数栈: 一个后进先出(Last-In-First-Out)的操作数栈,也可以称之为表达式栈(Expression Stack)。 操作数栈和局部变量表在访问方式上存在着较大差异,操作数栈并非采用访问索引的方式来进行数据访问的, 而是**通过标准的入栈和出栈操作来完成一次数据访问**。 每一个操作数栈都会拥有一个明确的栈深度用于存储数值,一个32bit的数值可以用一个单位的栈深度来存储,而2个单位的栈深度则可以保存一个64bit的数值, 当然操作数栈所需的容量大小在编译期就可以被完全确定下来,并保存在方法的Code属性中。 可以通过 -Xss 这个虚拟机参数来指定每个线程的 Java 虚拟机栈内存大小: java -Xss512M HackTheJava 该区域可能抛出以下异常:

一、JVM — Java内存区域

前提是你 提交于 2020-03-09 05:16:11
Java 内存区域详解 写在前面 (常见面试题) 基本问题 拓展问题 一 概述 二 运行时数据区域 2.1 程序计数器 2.2 Java 虚拟机栈 2.3 本地方法栈 2.4 堆 2.5 方法区 2.5.1 方法区和永久代的关系 2.5.2 常用参数 2.5.3 为什么要将永久代 (PermGen) 替换为元空间 (MetaSpace) 呢? 2.6 运行时常量池 2.7 直接内存 三 HotSpot 虚拟机对象探秘 3.1 对象的创建 Step1:类加载检查 Step2:分配内存 Step3:初始化零值 Step4:设置对象头 Step5:执行 init 方法 3.2 对象的内存布局 3.3 对象的访问定位 四 重点补充内容 4.1 String 类和常量池 4.2 String s1 = new String("abc");这句话创建了几个字符串对象? 4.3 8 种基本类型的包装类和常量池 参考 Java 内存区域详解 如果没有特殊说明,都是针对的是 HotSpot 虚拟机。 写在前面 (常见面试题) 基本问题 介绍下 Java 内存区域(运行时数据区) Java 对象的创建过程(五步,建议能默写出来并且要知道每一步虚拟机做了什么) 对象的访问定位的两种方式(句柄和直接指针两种方式) 拓展问题 String 类和常量池 8 种基本类型的包装类和常量池 一 概述 对于 Java

Java内存区域

耗尽温柔 提交于 2020-03-09 05:15:53
运行时数据区域: 程序计数器 : 通过改变计数器的值来选取下一条字节码指令,为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,即“线程私有”如果线程执行的是Java方法,那么计数器记录的是正在执行的虚拟机字节码指令的地址,如果是native方法,则计数器的值为空,此区域没有OutOfMemoryError情况。 Java虚拟机栈 : 线程私有,描述Java方法执行的内存模型,每个方法都会创建栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等。。方法调用直至完成,对应栈帧入栈到出栈。局部变量表内存空间在编译期间完成分配,运行期间不会改变其大小。线程请求栈的深度大于所允许的深度,则抛出StackOverflowError异常;如果扩展时无法申请到足够的内存,就抛出OutOfMemoryError异常。 设置本地方法栈大小-Xoss(其实无效,应使用后面的),栈容量只由-Xss设定。 单个线程下,抛出的都是StackOverflowError。 如果是建立过多线程导致的内存溢出,可以通过减少最大堆和减少栈容量(每个线程被分配到的栈大小)来换取更多的线程。 本地方法栈 : 执行Native方法,会有StackOverflowError和OutOfMemoryError异常。 Java堆 : jvm中最大的一块,线程共享,唯一目的是存放对象实例