C++常见面试题知识点
以下仅为个人思路,有错还望大家及时指出。
1.C++内存空间
参考链接:C++函数调用内存分配机制_zhongguoren666的博客-CSDN博客
线程的堆和栈_JackLiu16的博客-CSDN博客_线程是在堆上还是栈上
C/C++变量在内存中的分布_MoreWindows的博客-CSDN博客
C/C++程序内存的分配_cherrydreamsover的博客-CSDN博客_c++内存分配
C/C++动态内存管理malloc/new、free/delete的异同_cherrydreamsover的博客-CSDN博客
C/C++动态内存管理malloc/new、free/delete的异同_cherrydreamsover的博客-CSDN博客
C++主要可分为静态区和动态区。其中C/C++程序内存的分配这篇博客是精髓。
1)栈区(stack):由编译器自动分配与释放,存放为运行时函数分配的局部变量、函数参数、返回数据、返回地址等。其操作类似于数据结构中的栈。
2)堆区(heap):一般由程序员自动分配,需要手动释放,如果程序员没有释放,程序结束时可能有OS回收。其分配类似于链表。
3)全局区(静态区static):存放全局变量、静态数据、常量。程序结束后由系统释放。全局区分为已初始化全局区(data)和未初始化全局区(bss)。
4)常量区(文字常量区):存放常量字符串,程序结束后有系统释放。
5)代码区:存放函数体(类成员函数和全局区)的二进制代码。
补充:
1)每个线程一个栈,每个进程一个堆。线程允许共享的是堆中的数据。
参考:
堆栈 和 线程堆栈的问题-CSDN论坛
一个进程中各线程的堆和栈的关系_大爱李志的博客-CSDN博客_一个进程几个堆几个栈
2)char* 与char[]
char* 与char[]的内存分配方式比较古灵精怪。char* 分配在常量区,char[]分配在栈区。
参考:
C语言 char*和char[]用法_imxlw00的博客-CSDN博客_c char*
举个例子便可马上理解:
char* ch1() {char s[] = "123456";//分配在栈区s[1] = '9';return s;
}
char* ch2() {char* s = "123456";//分配在常量区//s[1]='2'//因为是分配在常量区,因此这个会报错return s;
}int main()//int argc,char** argv
{char* s=ch1();// cout << sizeof(s) << endl;for (int i = 0; i != 6; ++i)cout << s[i] << endl;
//无法正常打印,因为ch1()中返回的指针指向一个栈中的地址,而栈在离开作用域后内存会被释放cout << "*********************" << endl;s = ch2();for (int i = 0; i != 6; ++i)cout << s[i] << endl;
//可正常打印,因为ch2()中返回的指针指向一个常量区中的地址,其离开作用域后不会被释放return 0;
}
有可能char* s = "123456"语句会报错,具体原因可参考:
const char*(字符串常量)能否赋值给char*
2.类的数据成员与函数
首先要了解this指针,可参考:
【P115 33】C++ 对象特性—this指针和空指针_R-G-B的博客-CSDN博客_c++ this指针为空
c++中this指针的用法详解_程小二的博客-CSDN博客_c++this指针的用法
C++中this指针的理解和用法_小海歌哥的博客-CSDN博客_this指针的作用和用法
还有虚函数与虚表指针,可参考:
阿里云二面:C++ 虚表?
C++虚函数的调用过程_Currybeefer的博客-CSDN博客_c++虚函数调用
以及thiscall的函数调用方式,可参考:
_thiscall调用约定的简单概念_衣兜的博客-CSDN博客_thiscall调用约定
六. 函数调用约定与系统调用 - 知乎
还有最后这个强力推荐的文章,用C语言去详细描述了C++的封装继承和多态的特性:
看之前了解一下结构体指针的强转:计算结构体的大小 - 小乖不乖 - 博客园
struct s1 {int a = 1;int b = 0;
};
struct s2 {long long c = 0;
};
int main()//int argc,char** argv
{s1 ss;;s2* sss = (s2*)&ss;cout << sss->c << endl;//会打印1
}
参考链接:C语言的高级用法,面向对象
1)类的所有对象共享同一个成员函数的地址空间,而每个对象有独立的成员变量地址空间,可以说成员函数是类拥有的,成员变量是对象拥有的;不过如果类里有虚函数会多出一个虚函数表指针。
class vir {
public:int i;//占据一个数据成员int size = sizeof(*this);//占据一个数据成员void q() { cout << "q()" << endl; };//普通函数不占据virtual void q1() { cout << "vir" << endl; };//有虚函数,占据一个虚函数表指针virtual void q2() {};vir() {//构造函数不占据}
};
int main()//int argc,char** argv
{virson vs;cout << vs.size << endl;//最终打印为12字节return 0;
}
2)类的成员函数的默认形参中其实还隐含了一个this指针。
class B {
public:void p() { cout << "p()" << endl; };//其实是void p(B* this)virtual void vp() { cout << "vp()" << endl; };//其实是void vp(B* this)
};
int main()
{((B*) nullptr)->p();//可正常打印,因为该函数中没有使用到成员变量,即使this为空指针也能允许((B*) nullptr)->vp();//报错,因为使用虚函数先要从this指向的对象空间中索引出虚表指针
}
3)在构造函数中调用虚函数
最好不要这样干,但并非不行。
class vir {
public:int i;//占据一个数据成员int size = sizeof(*this);void q() { cout << "vir" << endl; };virtual void q1() { cout << "vir" << endl<<size<<endl; };virtual void q2() {};vir() {q1();//打印vir}
};class virson:public vir {
public:virtual void q1() { cout << "virson" << endl; };//virtual void q2() {};virson() {q1();//打印vson}
};
int main()
{vir* v = new virson();//vir类型的指针所允许的调用权限仅为vir中拥有的,具有截断性}
上面可以说明在执行构造函数作用域之前就已经为this开辟好空间并进行初始化了,并且this指针指向的是new出来的类型的空间。
这说明那个时候this指向的空间中的虚函数表指针已经指向virson对应的虚函数表了。
进一步而参考:c++ 构造函数中调用虚函数的实现方法
3.虚析构函数与内存泄漏
析构函数没用好,很可能会造成内存泄漏。通过上面的分析能比较好地清楚为啥有的析构函数是要用虚函数了。可参考:
虚函数、虚析构函数的缺点 - CLive Studio - 博客园
C++中虚析构函数的作用及其原理分析_逐鹿之城的博客-CSDN博客_虚析构函数的作用
对于虚析构函数的理解_xld_hung的博客-CSDN博客_虚析构函数
大致总结一下:如果析构函数不加virtual,那么会按照普通成员函数的调用方式,即指针类型去索引到该函数,这样的话就会调用到基类的析构函数。但是当加上virtual之后,其是要通过指针对应的数据类型去里面调用虚函数表指针索引到相应的函数,这时候才会调用派生类所对应的析构函数了。而执行了派生类的析构函数会自动再去调用基类的析构函数,因此在基类中采用虚析构函数,在delete一个指向派生类的基类指针时会执行派生类跟基类的析构函数。
下面举个例子说明会内存泄漏的情况:
class vir {
public:int size = sizeof(*this);int i;void q() { cout << "q()" << endl; };virtual void q1() { cout << "vir" << endl<<size<<endl; };//有虚函数,占据一个虚函数表指针vir() {//构造函数不占据q1();}virtual ~vir() { cout << "virdelete" << endl;q1();cout << i << endl;//能正常打印,i=90,说明执行virson的时候并没有把vir中的部分删除}
};class virson:public vir {
public:virtual void q1() {cout << "virson" << endl;};int* s = new int(3);virson() {// q1();}virtual ~virson() {q1();delete s;//如果不调用virson的析构函数,s指向的空间将变成野空间i = 90;}
};
int main()
{vir* vs = new virson;delete vs;
}
其他可参考:不用虚析构函数也不会造成内存泄漏的原因是什么?--CSDN问答
C++常见面试题知识点相关推荐
- Linux之常见面试题知识点批注(八)
温故: 54.crontab 文件由六个域组成 ,每个域之间用空格分割,其排列如下: (B) . A MIN HOUR DAY MONTH YEAR COMMAND B MIN HOUR DAY MO ...
- Java面试指北!13个认证授权常见面试题/知识点总结!| JavaGuide
大家好,我是 Guide哥!端午已过,又要开始工作学习啦! 我发现有很多小伙伴对认证授权方面的知识不是特别了解,搞不清 Session 认证.JWT 以及 Cookie 这些概念. 所以,根据我根据日 ...
- 常见面试题知识点之:分布式锁
1 分布式锁基本概念 1.1 基本概念 对缓存查询数据库的代码进行加锁,有两种方式: 本地锁 进程锁 具有局限性,只能在同一个项目中生效,不能控制另一个项目中的方式.保证同一时刻只有一个线程可访问共享 ...
- Android知识点汇总以及常见面试题
Android知识点汇总以及常见面试题 1. 链表和数组的区别 2. List Hash 数组的区别 3. 用过哪些三方SDK 4. Android四大组件 5. 堆和栈的区别 6. Activity ...
- Java知识点汇总以及常见面试题
Java知识点汇总以及常见面试题 1. "=="和equals()的区别 2. 构造方法能不能重写或者重载 3. 基本数据类型 4. 匿名内部类能被继承? 5. Integer和i ...
- Java常见面试题(持续更新)
文章目录 transient 关键字作用 final 关键字作用 封装的作用 HashMap,HashTable,ConcurrentHashMap HashMap不是线程安全的示例 HashMap常 ...
- 搞懂单链表常见面试题
搞懂单链表常见面试题 Hello 继上次的 搞懂基本排序算法,这个一星期,我总结了,我所学习和思考的单链表基础知识和常见面试题,这些题有的来自 <剑指 offer> ,有的来自<程序 ...
- 在单链表写入一组数据代码_链表常见操作和15道常见面试题
什么是单链表 链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针(Pointer),简单来说链表并不像数组那样 ...
- Python常见面试题:TCP 协议中的三次握手与四次挥手相关概念详解
今天来聊聊Python常见面试题中面试频率特别高的一个题目:TCP 协议中的三次握手与四次挥手. 涉及到的知识点有: 1.TCP.UDP 协议的区别 2.TCP 头部结构 3.三次握手与四次挥手过程详 ...
最新文章
- leetcode算法题--Minimum Depth of Binary Tree
- Linux TCP队列相关参数的总结
- 感染性的木马病毒分析之样本KWSUpreport.exe
- caged系统pdf_建筑行业单词中英文对照教材.pdf
- Hystrix原理讲解
- JVM虚拟机-Class文件之字段表集合
- Bootstrap学习(二)
- Ubuntu 12.04装五笔,同时又可以打拼音。
- iOS底层探索之类的结构(下):objc_setProperty
- mysql查询忽略字符编码是什么_MySQL 查询不区分大小写的问题以及编码格式问题...
- BUU Dest0g3 520迎新赛 WEB writeup
- 阿里云与华为USG防火墙IPSEC对接
- Ural 2045. Richness of words 打表找规律
- 母牛生小牛问题-字节跳动笔试题
- 给一个不多于5位的正整数,要求: 1.求出它是几位数; 2.分别输出每一位数字; 3.按逆序输出各位数字;
- GameFramework:StarForce资源讲解
- [Spring Boot] 2. Spring Boot 启动过程定制化
- Python 模拟登录淘宝
- 有这5款开源软件,语音转文字很简单!
- 程序员装机必备的软件
热门文章
- dnf跨几服务器比较稳定,DNF极具特色的几个跨区,跨6知名度最高,这个跨区打团不用挤频道...
- [jzoj 6305] 最小值 {单调栈}
- 新浪微博、微信朋友圈、qq空间分享---qq空间分享
- SCAU华南农业大学-数电实验-模4的可逆计数器-实验报告
- linux nfs配置参数,NFS常用参数
- 网络系统管理赛项之Debian 九. 2021年网络系统管理项目-模块A--样题(一)
- oracle like通配符区分大小写
- 我是怎么解决微信封了我们域名的
- 一个好的预发布环境应该是怎么样的?
- Locust 基本用法