Bootstrap

浩鲸云C++开发一面

目录

简述C++内存分配机制,存放在哪里?

详细说一下static

new,delete和mallco,free区别

指针和引用的区别

深拷贝和浅拷贝

在进程间使用管道进行通信的特点?

什么是内存泄漏,如何检测内存泄漏?

sizeof和strlen的区别

构造析构函数能否抛除异常,能否为虚函数?

​编辑

详述内存对齐

内联函数

详谈指针的初始化和释放

三个进程都需要对同一块内容进行读写操作,如何调度?


简述C++内存分配机制,存放在哪里?

  • 代码区:代码区存放程序员写的代码,准确来说是编译链接后生成的二进制机器指令。
  • 数据区:存放全局变量,静态变量,常量(字符串常量)等。
  • 堆区:由低地址向高地址增长,程序员手动分配的内存存储在这里。
  • 栈区:由高地址向低地址增长。由编译器自动管理分配,局部变量,函数参数变量,函数变量等存储在这里。

详细说一下static

  • 静态局部变量:只初始化一次,声明周期为全局。
  • 全局静态变量:只在当前文件中可以被使用,不能被其他文件所访问。
  • 静态类成员:属于类本身,与类一个级别,而不是和类的实例一个级别。
  • 在类内部声明的静态成员变量需要类外定义。
  • 静态函数:在类内部声明的静态成员函数。只能访问类内的静态成员变量和其他静态成员函数。

new,delete和mallco,free区别

  • 返回类型:new返回的是分配对象的类型的指针,而mallco返回的是void*类型,需要我们显示地转为需要的类型。
  • 调用构造函数new会自动调用对象构造函数,而malloc不会。这意味着new分配的对象会自被初始化,而malloc分配的对象需要手动初始化。
  • 内存:new可以根据对象类型自动确定分配内存的大小,malloc需要显示的指定要分配的内存大小。
  • 失败处理:new分配内存失败会抛std::bad_alloc异常,malloc不会抛异常,会返回NULL
  • 对数组的支持:new可以通过new []方式给数组分配内存,malloc不可以给数组分配内存。
  • 与delete/free的配对使用:new与delete配对,new[]与delete[]配对,malloc()与free()配对。

指针和引用的区别

  • 指针可以不初始化,但是引用必须要初始化。

  • 引用不能改变指向,因为引用就是该变量的别名,我就是你,不能再是别人。
  • 空值:指针可以为空(即不指向任何对象),引用不能为空。
  • 内存分配 :指针本身需要分配内存来存储地址,引用不需要,引用只是变量的别名。
  • 用途:指针常常用于动态内存分配,函数参数传递,数据结构的实现等场景。引用更多的是为了传参避免拷贝,提高性能
  •  安全性:引用比指针更安全,因为引用一旦初始化后就不能改变方向指向,减少了出错的可能性。指针提供了更多的灵活性和控制力,但是也需要更谨慎的使用。
     

深拷贝和浅拷贝

  • 内容复制:深拷贝复制对象的具体内容,包括引用的其他对象。浅拷贝只复制拷贝对象的值和地址,不复制引用的对象本身。
  • 内存地址:深拷贝自主分配新的内存地址,浅拷贝使用与原对象相同的地址。
  • 对象独立性:深拷贝的新对象与原对象完全独立,互相不干涉。浅拷贝新对象与原对象共享某些控件,会影响源对象。
  • 使用场景:深拷贝的使用场景为需要完全独立的新对象,修改新对象不影响原对象。浅拷贝的使用场景为原对象内容不易被修改,或可以接受影响原对象的情况。

在进程间使用管道进行通信的特点?

什么是进程通信?

什么是管道? 

一种抽象的理解为一个管道,一端有人放东西,另一端有人拿东西。

逻辑实现为文件的表现形式,向文件里写数据,从文件里读数据。

说的再准确一点管道就是一块缓冲区。

  • 管道的特点:
    •  管道是单项通信,即数据只能在一个方向上流动。一个进程写入数据,另一个进程读取数据。这种单向性使得管道的使用非常简单,但也限制了其使用场景。如果需要双向通信就需要再开一个管道。
    • 父子进程通信:管道常用于具有父子关系的进程间的通信。创建管道的进程(通常为父进程)可以将管道的文件描述符传递给子进程,从而实现父子进程通信。
    • 无名字:管道没有名字,它只能用于具有亲缘关系的进程间通信,即一个管道只能由创建它的进程及其子进程来通信,这使得管道的使用场景非常有限。
    • 字节流:管道传输的是字节流,因此可以传输任意类型的数据,只要这些数据可以转换为字节序列。
    • 数据同步:管道提供了数据同步机制。写入进程在写入数据后会等待,直到读取进程读取完毕。反之同理,这种机制保证了数据完整性和一致性。
    • 未满不读,已满不写。未空不写,已空不读。读后删除。

什么是内存泄漏,如何检测内存泄漏?

内存泄漏常常是因为动态分配的内存没有释放,这将导致应用程序占用的内存持续增长,最终可能导致程序崩溃或系统资源耗尽。

sizeof和strlen的区别

sizeof是运算符,不是c++的内置函数,因此我们在调sizeof的时候可以省略()。

sizeof可以计算自定义类型对象的大小。

strlen()用来计算c风格字符串(char* str/const char*  str)的长度(不含结尾/0)

构造析构函数能否抛除异常,能否为虚函数?

  • 能否抛除异常

  • 能否为构造函数

总结:尽量避免在构造析构函数中抛除异常。构造函数不可以为虚函数,析构函数可以为虚函数。

详述内存对齐

背景:

终极目的:空间换时间。

在C++中的应用:

对齐规则:

内联函数

内联也就是嵌套的意思。

详谈指针的初始化和释放

初始化

释放

三个进程都需要对同一块内容进行读写操作,如何调度?

为了避免竞态条件,可以有以下几个方案。

1.互斥锁

2.读写锁

3.条件变量

;