计算机,  随想

C++总结

数据结构

智能指针

① unique_ptr指针:对于一个指向开辟在堆区内存的指针,在整个指针作用域中指向这片内存区域的指针只能是他自己,谁要跟它抢夺控制权,编译器就会直接报错;

② shared_ptr指针:对于开辟在堆区的内存,我可以使用多个指针指向它,就相当于我先在堆区开辟一块内存使用一个指针指向这片内存区域,然后给这个指针取很多个别名

④ weak_ptr指针:用于解决使用“循环引用”的问题时,使用weak_ptr而非shared_ptr,与shared_ptr不同,weak_ptr是弱共享指针,当一个shared_ptr指针赋值给weak_ptr指针时,引用计数不会改变。

mojom管道 先定义数据结构和接口,然后引用头文件

测试

语言特性

强类型

变量都是要std::move复用的

作用域

头文件

callback

用法:

  1. FuncA() 调用 FuncB(param, Base::BindOnce(&FuncACallback()))
  2. FuncACallback() 对返回的参数做具体的处理
  3. using xxCallback = base::OnceCallback<void(a,b)>
  4. move().Run()
  5. Func2(paramx , &Base::BindOnce(&Func3,param1,param2,std::move(callback)))
  6. callback.Run(param3,param4);
  7. Func3(param1,param2,param3,param4)

本质:函数指针

高级特性

boost v8 base absl

base::Value

浏览器原理

注入

ETH注入,DidCreateScriptContext,AddJavaScriptObjectToFrame,BindFunctionsToObject 绑定V8对象,注入后才能在控制台调用方法

进程通信

浏览器进程

render process

browser process

utility process

通信

浏览器对象的生命周期不像http请求,是顺序执行的。而是伴随浏览器长期存在。在浏览器做不同的操作会执行不同进程的函数。

mojom和idl

mojom通信接口不能传null,否则会crash

x.reset 重置变量生命周期

mojo::Remote 发送端

mojo::Receive 接收端

交互流程

存储

SQLite

内存变量 会过期

TPM 硬件保存 安全性高

其他文章 炮轰C++

知识点总结

7、​​​​​​​new和malloc的区别?

new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持;

使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。

new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。

new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。

new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。

8、​​​​​​​new和delete的实现原理, delete是如何知道释放内存的大小的?

new简单类型直接调用operator new分配内存;而对于复杂结构,先调用operator new分配内存,然后在分配的内存上调用构造函数;对于简单类型,new[]计算好大小后调用operator new;对于复杂数据结构,new[]先调用operator new[]分配内存,然后在p的前四个字节写入数组大小n,然后调用n次构造函数,针对复杂类型,new[]会额外存储数组大小;

new表达式调用一个名为operator new(operator new[])函数,分配一块足够大的、原始的、未命名的内存空间;

编译器运行相应的构造函数以构造这些对象,并为其传入初始值;

对象被分配了空间并构造完成,返回一个指向该对象的指针。

delete简单数据类型默认只是调用free函数;复杂数据类型先调用析构函数再调用operator delete;针对简单类型,delete和delete[]等同。假设指针p指向new[]分配的内存。因为要4字节存储数组大小,实际分配的内存地址为[p-4],系统记录的也是这个地址。delete[]实际释放的就是p-4指向的内存。而delete会直接释放p指向的内存,这个内存根本没有被系统记录,所以会崩溃。

需要在 new [] 一个对象数组时,需要保存数组的维度,C++ 的做法是在分配数组空间时多分配了 4 个字节的大小,专门保存数组的大小,在 delete [] 时就可以取出这个保存的数,就知道了需要调用析构函数多少次了。

​​​​​​​9、malloc与free的实现原理?

在标准C库中,提供了malloc/free函数分配释放内存,这两个函数底层是由brk、mmap、,munmap这些系统调用实现的;

brk是将数据段(.data)的最高地址指针_edata往高地址推,mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存。这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系;

malloc小于128k的内存,使用brk分配内存,将_edata往高地址推;malloc大于128k的内存,使用mmap分配内存,在堆和栈之间找一块空闲内存分配;brk分配的内存需要等到高地址内存释放以后才能释放,而mmap分配的内存可以单独释放。当最高地址空间的空闲内存超过128K(可由M_TRIM_THRESHOLD选项调节)时,执行内存紧缩操作(trim)。在上一个步骤free的时候,发现最高地址空闲内存超过128K,于是内存紧缩。

malloc是从堆里面申请内存,也就是说函数返回的指针是指向堆里面的一块内存。操作系统中有一个记录空闲内存地址的链表。当操作系统收到程序的申请时,就会遍历该链表,然后就寻找第一个空间大于所申请空间的堆结点,然后就将该结点从空闲结点链表中删除,并将该结点的空间分配给程序

​​​​​​​10、malloc申请的存储空间能用delete释放吗?

不能,malloc /free主要为了兼容C,new和delete 完全可以取代malloc /free的。malloc /free的操作对象都是必须明确大小的。而且不能用在动态类上。new 和delete会自动进行类型检查和大小,malloc/free不能执行构造函数与析构函数,所以动态对象它是不行的。当然从理论上说使用malloc申请的内存是可以通过delete释放的。不过一般不这样写的。而且也不能保证每个C++的运行时都能正常。

最后更新于 2023年2月6日 by qlili

0 0 votes
Article Rating
Subscribe
Notify of
guest

1 Comment
Newest
Oldest Most Voted
Inline Feedbacks
View all comments
1
0
Would love your thoughts, please comment.x
()
x