第二节 · 封印符文 · 智能指针
Last updated
Last updated
int main()
{
int* p = new int(42); // 在堆上分配一个 int
cout << *p << endl; // 42
delete p; // 手动释放
p = nullptr; // 好习惯:置空
return 0;
}// 动态数组
int* arr = new int[10];
for (int i = 0; i < 10; ++i)
{
arr[i] = i * i;
}
// 释放数组要用 delete[]
delete[] arr; // 不是 delete arr!// 1. 内存泄漏 - 忘记 delete
void leak()
{
int* p = new int(42);
// 忘记 delete p;
} // p 销毁了,但分配的内存还在!
// 2. 重复释放
int* p = new int(42);
delete p;
delete p; // 错误!未定义行为
// 3. 使用已释放的内存(悬空指针)
int* p = new int(42);
delete p;
cout << *p << endl; // 错误!p 指向的内存已释放
// 4. 数组用错了 delete
int* arr = new int[10];
delete arr; // 错误!应该用 delete[]class Person
{
public:
string name;
int age;
Person(string n, int a) : name(n), age(a)
{
cout << name << " created" << endl;
}
~Person()
{
cout << name << " destroyed" << endl;
}
};
int main()
{
// 栈上创建
Person p1("Alice", 25);
// 堆上创建
Person* p2 = new Person("Bob", 30);
delete p2; // 调用析构函数,释放内存
return 0;
} // p1 自动销毁// 不好的做法 - 调用者需要记得 delete
int* createArray(int size)
{
return new int[size];
}
// 使用
int* arr = createArray(10);
// ... 使用 arr ...
delete[] arr; // 容易忘记!
// 更好的做法 - 使用容器
vector<int> createVector(int size)
{
return vector<int>(size);
}// 1. 需要控制对象生命周期
class Connection
{
public:
static Connection* create()
{
return new Connection();
}
void close()
{
delete this; // 对象自己删除自己
}
};
// 2. 需要大量内存
void processLargeData()
{
// 栈可能溢出
// int arr[10000000]; // 危险!
// 用堆更安全
int* arr = new int[10000000];
// ...
delete[] arr;
}
// 3. 运行时才知道大小
void dynamicSize(int n)
{
int* arr = new int[n]; // n 是运行时确定的
// ...
delete[] arr;
}