C++面试宝典总结delete/delete[]
·
前言
一、delete与delete[]
1.作用
delete和delete[]都是用于释放动态分配的内存的操作符
2.区别
| 操作符 | 作用 | 调用析构函数次数 | 适用场景 |
| delete | 释放单个对象/数组的首元素内存 | 只调用一次析构函数(对首元素) | 配合new分配的单个对象 |
| delete[] | 释放整个数组的内存 | 对数组中每个元素调用析构函数 | 配合new[]分配ide数组 |
delete:
假设指针指向一个通过new分配的对象
仅调用一次析构函数(如果对象有析构函数)
释放指针指向的内存块
delete[]:
假设指针指向一个通过new[]分配的数组首地址
对数组中的每个元素依次调用析构函数(从最后一个元素到第一个)
释放整个数组的内存块
3.错误使用后果
用delete释放new[]分配的数组:
仅调用第一个元素的析构函数,其他元素的析构函数被跳过(可能导致资源泄漏,如未释放的文件句柄、内存等)
内存泄漏或未定义行为
用delete[]释放new分配的单对象:
未定义行为(可能崩溃或内存损坏)
4.示例
4.1 delete示例
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() { cout << "Constructor\n"; }
~MyClass() { cout << "Destructor\n"; }
};
int main() {
// 单对象分配
MyClass* obj = new MyClass; // 调用构造函数
delete obj; // 调用析构函数
return 0;
}

4.2 delete[]示例
#include <iostream>
using namespace std;
class MyClass {
public:
MyClass() { cout << "Constructor\n"; }
~MyClass() { cout << "Destructor\n"; }
};
int main()
{
// 数组分配
MyClass* arr = new MyClass[3]; // 调用3次构造函数
delete[] arr; // 调用3次析构函数(逆序)
return 0;
}

二、C语言与C++有什么区别?
1.主要区别
|
特性 |
C语言 | C++ |
| 设计目标 | 过程式编程,贴近硬件 | 面向对象编程(OOP),兼容过程式 |
| 内存管理 | malloc/free | 手动管理/自动(RALL、智能指针) |
| 函数重载 | 不支持 | 支持 |
| 标准库 | stdio.hstdlib.h | STL、iostream等 |
| 运行效率 | 更高(无OOP开销) | 略低 |
2.示例说明
2.1编程规范
C语言:
// C语言:计算两个数的和
#include <stdio.h>
int add(int a, int b) {
return a + b;
}
int main() {
int x = 5, y = 3;
printf("Sum: %d\n", add(x, y));
return 0;
}
C++:支持面向对象编程(类、继承、多态)
// C++:用类封装加法逻辑
#include <iostream>
class Calculator {
public:
int add(int a, int b) { return a + b; }
};
int main() {
Calculator calc;
int x = 5, y = 3;
std::cout << "Sum: " << calc.add(x, y) << std::endl;
return 0;
}
2.2内存管理
C语言:必须手动管理 malloc/free
// C语言:动态分配数组
#include <stdio.h>
#include <stdlib.h>
int main() {
int* arr = (int*)malloc(5 * sizeof(int));
if (arr == NULL) {
printf("Memory allocation failed\n");
return 1;
}
arr[0] = 10;
free(arr); // 必须手动释放
return 0;
}
C++:手动管理/智能指针
// C++:使用智能指针管理内存
#include <iostream>
#include <memory>
int main() {
auto arr = std::make_unique<int[]>(5); // 自动释放
arr[0] = 10;
std::cout << arr[0] << std::endl;
return 0; // 无需手动释放
}
2.3函数重载
C语言:不支持函数重载,函数名必须不同
// C语言:通过不同函数名实现类似重载
#include <stdio.h>
void print_int(int x) { printf("Int: %d\n", x); }
void print_float(float x) { printf("Float: %f\n", x); }
int main() {
print_int(42);
print_float(3.14f);
return 0;
}
C++:支持函数重载,函数名相同,参数不同即可
// C++:函数重载
#include <iostream>
void print(int x) { std::cout << "Int: " << x << std::endl; }
void print(float x) { std::cout << "Float: " << x << std::endl; }
int main() {
print(42);
print(3.14f);
return 0;
}
2.4异常处理
C语言:无内置异常处理,需要通过返回值/errno检查错误
// C语言:通过返回值检查错误
#include <stdio.h>
#include <stdlib.h>
int divide(int a, int b, int* result) {
if (b == 0) return -1; // 错误码
*result = a / b;
return 0;
}
int main() {
int res;
if (divide(10, 0, &res) != 0) {
printf("Error: Division by zero\n");
}
return 0;
}
C++:支持try/catch异常处理
// C++:异常处理
#include <iostream>
#include <stdexcept>
int divide(int a, int b) {
if (b == 0) throw std::runtime_error("Division by zero");
return a / b;
}
int main() {
try {
std::cout << divide(10, 0) << std::endl;
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << std::endl;
}
return 0;
}
2.5泛型编程
C语言:无泛型编程
// C语言:用宏模拟泛型(不安全)
#include <stdio.h>
#define MAX(a, b) ((a) > (b) ? (a) : (b))
int main() {
printf("Max: %d\n", MAX(5, 3));
return 0;
}
C++:支持模板 泛型编程
// C++:模板函数
#include <iostream>
template <typename T>
T max(T a, T b) {
return a > b ? a : b;
}
int main() {
std::cout << "Max: " << max(5, 3) << std::endl;
std::cout << "Max: " << max(3.14, 2.71) << std::endl;
return 0;
}
更多推荐
所有评论(0)