每日面经(十七)

文章探讨了C++中引用和指针的区别,包括初始化、类型安全和空值等方面,并阐述了它们在函数参数传递和对象拷贝中的应用场景。接着讨论了拷贝构造函数与成员函数拷贝的区别,以及如何处理STL容器中迭代器失效的问题。最后,介绍了如何使用GDB调试多线程程序,包括查看线程堆栈信息。
摘要由CSDN通过智能技术生成

目录

1.引用跟指针的区别

2.为什么要有这些区别,与指针分别使用那些场景

3..C++拷贝构造函数与成员函数传人同类型的变量来进行拷贝的区别

4.vector以及STL各种容器的迭代器失效问题

5.场景题,两个容器中如果存放了相同指针,如果其中一个释放了一个在用怎么解决?

6.gdb调试器怎么调试多线程,怎么查看堆栈


1.引用跟指针的区别

引用和指针都可以用来间接访问变量,但是它们有以下区别:

  1. 指针可以被赋值为真正意义上的空值,即指向地址0。而引用必须总是绑定到某个对象上。

  2. 指针可以在声明时不初始化,而引用必须在声明时初始化。

  3. 指针可以指向不同类型的对象,而引用只能指向其所绑定对象的类型。

  4. 指针可以被重新指向另一个对象,而引用始终绑定到同一个对象上。

  5. 指针可以进行指针运算,而引用不能。

  6. 指向指针的指针可以通过多级间接访问对象,而引用只能通过单级间接访问对象。

  7. 引用一定不能为NULL,指针可以为空。

需要注意的是,虽然引用和指针有一些差异,但它们都提供了访问内存中对象的方式,具体使用时需要根据情况来选择。

2.为什么要有这些区别,与指针分别使用那些场景

这些区别是为了更加安全和高效地使用引用和指针。

引用适用于以下场景:

  1. 用于传递参数给函数,特别是当函数需要修改它们的值时,引用可以直接修改参数的值。

  2. 用于返回函数值,可以避免创建副本并提高代码的可读性。

  3. 避免了无效的指针检查,因此可以提高代码的可靠性和性能。

  4. 简化代码,因为不能为引用指定NULL,因此不需要检查引用是否为NULL。

指针适用于以下场景:

  1. 动态分配内存,因为可以使用指针来访问新分配的内存。

  2. 修改指向的对象的值。

  3. 当需要动态地控制指向对象的位置和生命周期时,可以使用指针。

因此,需要根据实际情况和要求来选择使用引用还是指针。一般来说,如果需要访问指向可变对象的指针,应该使用指针,而如果只需要访问对象而不需要修改它,应该使用引用。

3..C++拷贝构造函数与成员函数传人同类型的变量来进行拷贝的区别

C++拷贝构造函数和成员函数传入同类型的变量来进行拷贝的区别在于:

  1. 拷贝构造函数是特殊的构造函数,用于从一个已经存在的对象创建一个新的对象。它通常采用引用参数来传递需要拷贝的对象,以及一个新对象的引用,从而创建一个新的对象。而成员函数通过传入同类型的变量来进行拷贝,通常涉及到赋值操作。

  2. 在拷贝构造函数中,创建新对象的过程是由编译器自动完成的,它会按照已经存在对象的实例来创建新的对象。而成员函数需要显式地调用赋值操作来完成拷贝,操作的过程由开发人员手动完成。

  3. 拷贝构造函数只有在对象被传递给函数、从函数返回或者初始化对象数组等操作时才会被调用,而成员函数可以随时调用。

  4. 拷贝构造函数通常用于处理动态分配的内存,以避免浅拷贝(指针拷贝后两个指针指向同一块内存,可能会导致程序出错),而成员函数通常用于处理对象的共享状态。

需要注意的是,拷贝构造函数在实现时需要考虑到以下因素:复制构造函数参数的类型,保证创建对象时数据的合法性,以及如何进行深拷贝等。而使用成员函数进行拷贝时,需要手动处理浅拷贝问题,以避免对象在使用过程中出现错误。

4.vector以及STL各种容器的迭代器失效问题

在使用vector以及STL各种容器时,插入或删除操作可能会导致容器中元素的内部存储发生变化,从而导致迭代器失效。具体来说,插入或删除元素时,可能会导致已有元素的移动或内存分配的变化,这会导致原先指向某个元素的迭代器失效,即指向的元素地址对应的内容已发生改变或删除,使得迭代器指向的内存地址变得无效。使用失效的迭代器会导致程序出现不可预知的错误,因此需要注意避免这种情况的发生。

为了避免迭代器失效问题,在编写代码时可以采用以下几种方法:

  1. 尽量使用迭代器指向容器中的元素,而不是容器中的索引,因为元素的插入或删除不会影响其他元素的存储地址,从而避免迭代器失效。

  2. 对于需要删除或插入元素的操作,可以使用erase和insert成员函数提供的迭代器参数进行操作。这样可以避免由于操作导致已有元素的移动或内存分配变化,从而避免迭代器的失效。

  3. 对于需要对容器进行频繁的插入或删除操作的场景,可以考虑使用list容器,因为list容器的特点是可以快速插入和删除元素,并且不会影响其他元素在容器中的存储位置,从而避免迭代器失效的问题。

5.场景题,两个容器中如果存放了相同指针,如果其中一个释放了一个在用怎么解决?

综上所述,需要注意在使用vector以及STL各种容器时,若有插入或删除操作,要特别注意迭代器的失效问题,可以采用上述方法进行处理,以确保程序的正常运行。

如果两个容器中存放了相同指针,其中一个容器释放了这个指针,导致另一个容器使用这个指针时发生问题,可以采用以下几种方法解决:

  1. 在代码实现时,尽量避免两个容器存放相同指针的情况,比如可以对指针进行复制,而非直接将指针存入不同的容器中。

  2. 当一个容器释放了这个指针时,其它引用该指针的容器需要及时对其进行处理,比如将该指针从容器中移除或置空,避免在其它容器中使用已经被释放的指针。

  3. 设置该指针的引用计数,当其中一个容器释放该指针时,引用计数-1,只有所有引用计数为0时才真正进行内存释放,从而避免在其它容器中使用已经被释放的指针。

综上所述,当两个容器中存放了相同指针,其中一个容器释放了该指针后,需要在其它容器中对指针进行处理,以避免使用已经被释放的指针导致程序崩溃。

6.gdb调试器怎么调试多线程,怎么查看堆栈

在使用GDB调试多线程程序时,需要使用GDB的多线程调试功能。首先,你需要在编译时加入-g选项以生成调试信息。然后,在运行程序时,使用-gdb调试器启动程序,并在GDB的命令行中输入以下命令:

set follow-fork-mode child  # 如果程序是通过 fork() 来创建多个进程的,需要设置 follow-fork-mode 为 child
set follow-exec-mode new    # 如果程序是通过 exec() 来启动新进程的,需要设置 follow-exec-mode 为 new

然后,使用以下命令开始多线程调试:

set non-stop on      # 开启 non-stop 模式
set pagination off   # 关闭分页
set scheduling off   # 关闭调度
handle SIGSTOP pass  # 启用处理 SIGSTOP 信号
set target-async on  # 启用异步模式

接下来,可以使用以下命令来查看线程的信息:

info threads         # 显示所有线程的信息
thread [thread-id]   # 切换到指定线程

调试多线程程序时,有时需要查看每个线程的堆栈信息。使用以下命令可以显示当前线程的堆栈:

bt                   # 显示当前线程的堆栈信息

在多线程程序中,使用bt命令可以查看当前线程的堆栈信息。使用thread命令可以切换到其他线程并查看其堆栈信息。

给一些其他人的面试记录,挺有帮助的:

以代码的方式回看自己23届校招 | 或恐慌、疑惑、好在坚持!_牛客网

大疆DJI 嵌入式 2022.08.07_牛客网

MINIEYE自动驾驶公司 深圳 实习 2022.07.07_牛客网

百度提前批嵌入式 上海 2022.07_牛客网

深圳杰理科技嵌入式 2022.07.26_牛客网

深圳 诺瓦星云提前批 嵌入式 2022.08.06_牛客网

哲库科技 提前批 2022.08.07_牛客网

经纬恒润 自动驾驶嵌入式 2022.08.15_牛客网

丰疆智能 嵌入式软件开发_牛客网

🤷‍♂️一次让我略感疲惫的英文面试--吉利极氪 嵌入式软开_牛客网

🤷‍♂️【深信服校招】笔试+面试 软件开发工程师_牛客网

ZTE中兴软件工程师 一面+二面 2022.08.29_牛客网

紫光同芯 嵌入式软开 芯片 2022.09.19_牛客网

美团校招面经 嵌入式 1,2面 2022. 09_牛客网

360 软开 一面+二面+ 2022.09_牛客网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值