面试题答案
一键面试#include <iostream>
// 函数声明
void operateOnArray(int **arr, int rows, int cols);
int main() {
int rows = 3;
int cols = 4;
// 动态分配二维数组内存
int **arr = new int*[rows];
for (int i = 0; i < rows; ++i) {
arr[i] = new int[cols];
}
operateOnArray(arr, rows, cols);
// 输出数组内容
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << arr[i][j] << " ";
}
std::cout << std::endl;
}
// 释放内存
for (int i = 0; i < rows; ++i) {
delete[] arr[i];
}
delete[] arr;
return 0;
}
void operateOnArray(int **arr, int rows, int cols) {
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
arr[i][j] = i * j;
}
}
}
内存泄漏问题及避免方法
- 内存泄漏问题:
- 如果在动态分配二维数组的过程中,内层
new int[cols]
成功,但外层new int*[rows]
失败,由于已经分配了内层的内存,但没有对应的释放操作,会导致内存泄漏。 - 如果在释放内存时,忘记释放内层数组(即只执行
delete[] arr;
而没有先delete[] arr[i];
),也会导致内存泄漏。
- 如果在动态分配二维数组的过程中,内层
- 避免方法:
- 在分配内存时,采用异常安全的方式。例如,使用智能指针(下面会分析)。如果不使用智能指针,在分配内层数组后,立即检查是否分配成功,如果失败,先释放之前分配的外层数组内存。
- 在释放内存时,确保按照正确的顺序释放,先释放内层数组,再释放外层数组。
C++智能指针的适用性及使用方法
- 适用性:C++智能指针适用于这种场景,可以有效管理动态分配的内存,避免内存泄漏。
- 使用方法:
- 使用
std::unique_ptr
来管理二维数组。可以使用std::unique_ptr<int[]>
来管理内层数组,std::unique_ptr<std::unique_ptr<int[]>[]>
来管理外层数组。
- 使用
#include <iostream>
#include <memory>
// 函数声明
void operateOnArray(std::unique_ptr<std::unique_ptr<int[]>[]> &arr, int rows, int cols);
int main() {
int rows = 3;
int cols = 4;
// 动态分配二维数组内存
std::unique_ptr<std::unique_ptr<int[]>[]> arr(new std::unique_ptr<int[]>[rows]);
for (int i = 0; i < rows; ++i) {
arr[i].reset(new int[cols]);
}
operateOnArray(arr, rows, cols);
// 输出数组内容
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
std::cout << arr[i][j] << " ";
}
std::cout << std::endl;
}
// 智能指针会自动释放内存,无需手动释放
return 0;
}
void operateOnArray(std::unique_ptr<std::unique_ptr<int[]>[]> &arr, int rows, int cols) {
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
arr[i][j] = i * j;
}
}
}
这样,使用智能指针可以简化内存管理,并且在对象生命周期结束时自动释放内存,有效避免内存泄漏。