首页 > 编程语言 >C++面试八股文:什么是空指针/野指针/悬垂指针?

C++面试八股文:什么是空指针/野指针/悬垂指针?

时间:2023-06-30 23:45:14浏览次数:46  
标签:面试官 悬垂 int nullptr C++ 师兄 指针

某日二师兄参加XXX科技公司的C++工程师开发岗位第30面:

面试官:什么是空指针?

二师兄:一般我们将等于0/NULL/nullptr的指针称为空指针。空指针不能被解引用,但是可以对空指针取地址。

int* p = nullptr;	//空指针
*p = 42;	//空指针不可以解引用
int** pp = &p	//空指针可以取地址

面试官:你知道0/NULL/nullptr三者之间的区别吗?

二师兄:虽然三者都能定义空指针,但三者类型不同。

二师兄:0int类型,NULL在g++下是一个宏定义,而nullptr是有类型的;

#define NULL ((void *)0)

typedef decltype(nullptr) nullptr_t;

sizeof(0);// 4
sizeof(NULL);//8
sizeof(nullptr);//8

二师兄:在函数重载时,会根据实参的类型选择重载函数:

#include <iostream>
void fun(int) {std::cout << "int" << std::endl;}
void fun(int*) {std::cout << "int*" << std::endl;}
void fun(nullptr_t) {std::cout << "nullptr_t" << std::endl;}
int main(int argc, char const *argv[])
{
    fun(0);	//编译通过,匹配fun(int)
    fun(NULL);	//编译失败,可以匹配 fun(int) fun(int*) fun(nullptr_t)
    fun(nullptr);	//编译成功,匹配fun(nullptr_t)
    return 0;
}

二师兄:在C++11之后,建议使用nullptr定义空指针,因为它时有类型的,编译器能够对它进行类型检查。

面试官:什么是野指针?

二师兄:野指针突出一个野字,这个野就是状态未知的。它可能指向一块未知的区域:

int* p;		//野指针,指针未初始化
*p = 42;	//对野指针解引用,未定义的操作

面试官:什么是垂悬指针?

二师兄:垂悬指针是指指针指向的内容已被释放,指针指向的对象的生命周期已结束。

int* p = new int(42);
delete p;
*p = 1024;	//垂悬指针,指针指向的对象已被释放

int* p = nullptr;
{
    int i = 42;
    p = &i;
}
*p = 1024; //垂悬指针,指向的对象的生命周期已结束

面试官:如何解决空指针、野指针、垂悬指针带来的问题?

二师兄:主要可以从有以下几点入手:

1.在解引用指针之前,要判断指针是否为空。(解决空指针解引用问题)

2.对于定义的指针,一定要进行初始化(=nullptr)。(解决野指针问题)

3.对于释放过内容的指针,立即将指针置为nullptr。(解决垂悬指针、指针二次释放问题)

4.要注意长生命周期的指针不能指向短生命周期的对象。(解决垂悬指针问题)

5.C++11之后使用智能指针。

面试官:好的。那你知道什么是内存泄漏(memory leak)吗?

二师兄:内存泄漏是指分配的内存空间没有被正确释放的情况。常见的情况有malloc没有freenew没有deletenew[]delete混用。

面试官:如何防范内存泄漏问题?

二师兄:最简单的办法是使用资源获取即初始化(RAII)技术将资源放在类中管理,在类构造时获取资源(malloc/new),在类的析构函数中释放资源(free/delete),使用C++的构造和析构机制保证资源的正确申请和释放。

二师兄:我们常用的std::shared_ptrstd::unique_ptrstd::lock_guard就是采用这种技术管理资源。

面试官:最后一个问题,如何查找程序中是否出现了内存泄漏?

二师兄:只要有两种方法:

1.自己动手:把所有使用malloc/free的地方改成new/delete,重载全局的newdelete,并加入申请和释放内存容量的统计逻辑。

2.采用工具:可以使用诸如Valgrind(在Linux上)或Dr. Memory(在Windows上)等内存调试工具来检测内存泄漏。这些工具可以在运行程序时检测内存泄漏,并提供详细的报告和调试信息。

面试官:好的。今天的面试结束,请等消息。

今天的面试到这里就结束了,祝大家周末愉快~

关注我,带你21天“精通”C++!(狗头)

标签:面试官,悬垂,int,nullptr,C++,师兄,指针
From: https://www.cnblogs.com/binarch/p/17518039.html

相关文章

  • C++面试八股文:std::vector了解吗?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第23面:面试官:vector了解吗?二师兄:嗯,用过。面试官:那你知道vector底层是如何实现的吗?二师兄:vector底层使用动态数组来存储元素对象,同时使用size和capacity记录当前元素的数量和当前动态数组的容量。如果持续的push_back(empl......
  • 【c++基础】位域结构体
    前言code#include<iostream>typedefstruct{unsignedinta:5;unsignedintb:3;}tBits;intmain(){tBitsaa;aa.a=205;//11001101aa.b=89;//01011001std::cout<<"a:"<<aa.a<<......
  • C++中三个特殊的宏 __FILE__, __FUNCTION__ 和 __LINE__
    有一次在看代码时,发现如下代码:m_strClassFileName=__FILE__;  把 __FILE__赋给了一个变量.这是我第一次接触__FILE__,于是查找了一下,才发现它是C++中三个特殊的宏之一.C++中共有三个特殊的宏,分别是 __FILE__,__FUNCTION__和__LINE__......
  • C++代码中字符串分多行时的情况
    #include<iostream>intmain(constintargc,constchar*argv[]){std::stringstrSql1="select*fromtable\whereid=1\andname='name'";std::cout<<strSql1<<std::endl;std::stringst......
  • C++面试八股文:什么是构造函数?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第29面:面试官:什么是构造函数?二师兄:构造函数是一种特殊的成员函数,用于创建和初始化类的对象。构造函数的名称与类的名称相同,并且没有返回类型。构造函数在对象被创建时自动调用。structFoo{Foo(intv):val(i){} //构造函数p......
  • C++面试八股文:什么是构造函数?
    某日二师兄参加XXX科技公司的C++工程师开发岗位第29面:面试官:什么是构造函数?二师兄:构造函数是一种特殊的成员函数,用于创建和初始化类的对象。构造函数的名称与类的名称相同,并且没有返回类型。构造函数在对象被创建时自动调用。structFoo{Foo(intv):val(i){} //构造函数......
  • c++实现装饰器模式
    1、构建基本类的抽象#include<iostream>classIComponent{public:virtualvoidOperate()=0;private:};2、构建基本类classComponent:publicIComponent{public:voidOperate()override{std::cout<<"基础操作......
  • C++ 编程中的核心知识点!
    const作用修饰变量,说明该变量不可以被改变;修饰指针,分为指向常量的指针(pointertoconst)和自身是常量的指针(常量指针,constpointer);修饰引用,指向常量的引用(referencetoconst),用于形参类型,即避免了拷贝,又避免了函数对值的修改;修饰成员函数,说明该成员函数内不能修改成员......
  • 指针
    原文地址:https://www.cnblogs.com/liqinglucky/p/pointer.html在计算机中,数据都是存放于内存单元中。每个内存单元就是数据的存放地址。这样存放地址就指向我们定义的变量,指针就是内存单元的地址。#include<stdio.h>voidmain(void){int*p1,a=1;void*p2;......
  • 指针将值传递
    原文地址:https://www.cnblogs.com/liqinglucky/p/pointer_value.html指针#include<stdio.h>voidmsg(int*in,int*out){int*sen;int*rec;sen=in;//send的地址通过in赋值给senrec=out;//recv的地址通过out赋值给rec*rec=*sen;//改变rec存放......