2025年C/C++基础面试题全解析 | 突破技术盲区,直击大厂核心考点
导语:C/C++作为底层开发的核心语言,其面试考察点既包含基础语法陷阱,也涉及系统级编程思维。本文精选20道高频基础面试题,结合大厂真题与底层实现原理,从内存管理到多态实现,从指针操作到STL源码,助你构建完整的知识体系。文末附赠面试避坑指南,建议收藏研读!
一、内存管理:程序员的炼金术 🔥
1. new/delete与malloc/free的九重差异
- 类型安全:new返回类型指针,malloc返回void*需强制转换
- 构造析构:new触发构造函数,malloc仅分配裸内存
- 内存计算:
new int[10]
自动计算空间,malloc需手动计算字节数 - 异常处理:new失败抛bad_alloc异常,malloc返回NULL
// 经典错误案例
int* p = (int*)malloc(sizeof(int)*10);
p[10] = 0; // 越界访问(堆内存无边界检查)
2. 智能指针的三重境界
- unique_ptr:独占所有权,移动语义传递(禁用拷贝构造)
- shared_ptr:引用计数+控制块,循环引用需搭配weak_ptr
- 自定义删除器:
shared_ptr<FILE>(fopen(...), [](FILE* fp){fclose(fp);})
3. 内存泄漏检测六脉神剑
- Valgrind工具链:
--track-origins=yes
追踪未初始化内存 - 重载operator new:记录分配位置(__FILE__和__LINE__宏)
- RAII封装:通过作用域生命周期自动释放资源
二、指针与引用:C++的灵魂拷问 💀
1. 指针与引用的七层本质差异
特性 | 指针 | 引用 |
---|---|---|
空值合法性 | 可赋值为NULL | 必须绑定有效对象 |
重绑定 | 可修改指向 | 初始化后不可变更 |
多级间接 | 支持多级指针(int**) | 仅一级引用 |
内存占用 | 占用独立内存空间 | 作为别名不额外占用内存 |
算术运算 | 支持指针算术 | 不支持 |
类型安全 | 可能产生类型转换风险 | 严格类型匹配 |
函数参数传递 | 传递地址值 | 传递对象别名 4 5 |
2. const关键字的四重封印
- 常量指针:
const int* p
(指向内容不可变) - 指针常量:
int* const p
(指针本身不可变) - 常量成员函数:
void func() const
(禁止修改成员变量) - 常量引用参数:
void print(const string& str)
(避免拷贝,保护原数据)
三、面向对象:虚函数背后的黑魔法 ✨
1. 虚函数表(vTable)内存布局
class Animal {
public:virtual void eat() { cout << "Animal eat"; }int age;
};
class Cat : public Animal {
public:virtual void meow() { cout << "meow"; }
};// 内存结构
| vptr | Animal::age | Cat扩展数据 |↓vTable → [&Animal::eat][&Cat::meow] [8](@ref)
2. 多态实现的三种形态
- 编译时多态:函数重载、模板特化
- 运行时多态:虚函数+继承体系(动态绑定)
- 类型识别:
typeid
和dynamic_cast
(需开启RTTI)
3. 纯虚函数设计哲学
- 接口抽象:
virtual void draw() = 0
强制子类实现 - 工厂模式基石:通过基类指针创建不同子类对象
- 虚析构必要性:防止基类指针删除子类对象时内存泄漏
四、STL源码级灵魂拷问 🛠️
1. vector的扩容奥秘
- 倍增策略:VS采用1.5倍扩容(避免内存碎片),GCC采用2倍扩容(时间换空间)
- 迭代器失效:
push_back
导致扩容时,原有迭代器全部失效 - emplace_back优化:完美转发避免临时对象构造
2. map的红黑树实现
- 节点结构:颜色标记+父指针+左右子指针
- 插入平衡:左旋/右旋+颜色翻转(保证O(logN)复杂度)
- 与unordered_map对比:红黑树保证有序性,哈希表追求O(1)访问
五、经典算法手撕指南 📝
1. 链表操作三连击
// 双向链表节点删除
void deleteNode(Node* node) {node->prev->next = node->next;node->next->prev = node->prev;delete node;
} [1](@ref)
2. 排序算法性能对比
算法 | 时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|
快速排序 | O(n logn) | O(1) | 否 |
归并排序 | O(n logn) | O(n) | 是 |
堆排序 | O(n logn) | O(1) | 否 |
冒泡排序 | O(n²) | O(1) | 是 1 4 |
面试避坑指南 ⚠️
-
手写strcpy陷阱
- 未检查源指针NULL
- 未处理内存重叠区域(memmove更安全)
- 忘记追加'\0'终止符
-
sizeof终极考题
char str[] = "Hello"; // sizeof(str)=6(含'\0')
void func(char arr[100]) { sizeof(arr)=4/8(退化为指针) } [2,5](@ref)
- 项目经验包装术
- 用Valgrind优化内存泄漏(量化减少百分比)
- 多线程下智能指针使用案例
- STL容器选型优化(vector vs list)
结语:掌握基础方能筑就高阶,本文涉及的每个知识点都对应着实际开发中的关键决策点。
【C语言】五小时快速入门C语言
【C语言】零基础到项目实战
【C++】项目实战-婚恋交友系统