讲一下static关键字的作用?
1. 全局静态变量
在全局变量前加上static关键字,全局变量就成了全局静态变量,它在数据段上存放,且在整个程序的运行期间一直都存在.未经初始化的全局变量的值会被自动初始化为0,全局静态变量在声明它的文件之外是不可见的,只在本文件可见。
2. 局部静态变量
在局部静态变量前加上static关键字后,局部变量就成了局部静态变量,局部静态变量也是存储在数据段,其作用域仍为局部作用域,当定义它的语句块或函数结束的时候,作用域也结束,但是当它离开作用域后,并没有被销毁,而是驻留在内存中,直到该函数被再次调用,并且值不变。
3. 静态函数
在函数的返回值前加上static关键字后,函数就被声明成了静态函数,静态函数只在本文件中可用,不会同其他的文件中同名函数命名冲突。
4. 类的静态成员
静态成员可以实现多个对象之间进行数据共享,静态成员是类中所有对象的共享的成员,对多个对象来说,静态成员只存储一处,供多个对象共享。
5. 类的静态函数
静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象的成员,因此对静态成员的引用不需要使用对象名。在静态成员的实现中,不能直接调用类中说明的非静态成员。如果静态成员函数中需要引用非静态成员时,可以通过对象来引用。
指针和数组名的区别?
- 数组名不能自增和自减,而指针可以。
- 数组名的内涵在于指代的实体是指一种数据结构-数组,指针只是存放了一个地址。数组名的外延在于其可以转换为转换为指向其指代实体的指针,而且是一个常量指针(arr[i] = *(arr + i))。指针是一个变量指针。
- 数组名取地址得到的是数组名所指元素的地址。对指针取地址得到的是指针变量自身的地址。
- 当对数组名使用sizeof时,得到的是数组元素的个数乘元素类型的字节数,对指针sizeof得到的是指针类型的字节数。
指针和引用的区别?
- 指针有自己的一块空间,而引用只是一个别名。
- 使用sizeof看一个指针的大小是4,而引用则是被引用的对象的大小。
- 指针可以被初始化为NULL,而引用必须被初始化且必须是一个已有对象的引用。而且不能被改变,指针可以改变指向。
- 作为参数传递时,指针必须解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象。
- 可以有const指针,但是没有const引用。
- 指针可以有多级指针,引用只能有一级。
讲一下什么是内存泄漏?如何检测?
内存泄漏是指由于疏忽造成了程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是程序分配某一段内存以后,由于设计的错误,失去了对该段内存的控制,造成内存的浪费。
- 内存泄漏的分类:
- 堆内存泄漏。堆内存时程序运行过程中根据需要,通过malloc,remalloc,new等从 堆上分配的一块内存,如果没有进行调用对应的free和delete,那么此后这块内存将不再会被使用,就会产生堆内存的泄漏。
- 系统资源泄漏。主要指系统分配的资源比如Bitmap,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费。
- 没有将基类的析构函数定义为虚函数。当基类的指针指向子类对象时,如果基类的析构函数不是virtual,那么子类的析构函数不会被调用,子类的资源没有正确释放,造成内存泄漏。
- 内存泄漏的检测:
Linux下可以使用内存泄漏的检测工具Valgrind,另一方面,我们可以在写代码的时候,添加内存申请和释放的统计功能,统计当前内存申请的和释放的是否一致,以此来判断是否发生内存泄漏。
说一下new和malloc的区别:
- new分配内存是按照数据类型进行分配,malloc分配内存是按照指定大小分配。
- new返回的是指定对象的指针,malloc返回的是void*,需要进行强制类型转换。
- new不仅会分配一段内存,还会调用构造,malloc不会。
- new是一个操作符,可以进行重载,malloc是一个库函数。
- new分配失败会抛出bad_malloc的异常,malloc则会返回NULL。
- 申请数组时,new[] 一次分配所有内存,多次调用构造,搭配使用delete[] ,delete[]多次调用析构函数,销毁数组中的每一个对象。而malloc只能用sizeof(int)* n 。