指针初始化策略
- 立即初始化:在声明指针变量时,马上给它赋一个合理的值,如
nullptr
。例如:
MyClass* ptr = nullptr;
- 构造函数初始化:对于类中的指针成员变量,在构造函数的初始化列表中进行初始化。
class MyClass {
AnotherClass* anotherPtr;
public:
MyClass() : anotherPtr(nullptr) {}
};
智能指针的运用
- std::unique_ptr:用于独占式资源管理,当
std::unique_ptr
离开作用域时,它所指向的对象会被自动释放。例如:
std::unique_ptr<MyComplexObject> obj = std::make_unique<MyComplexObject>();
- std::shared_ptr:用于共享式资源管理,通过引用计数来控制对象的生命周期。当引用计数为0时,对象被释放。适用于多个部分需要访问同一对象的场景。
std::shared_ptr<CommonResource> resource = std::make_shared<CommonResource>();
- std::weak_ptr:与
std::shared_ptr
配合使用,解决循环引用问题。std::weak_ptr
不增加引用计数,它可以观察std::shared_ptr
所管理的对象,但不会阻止对象被释放。
std::shared_ptr<ClassA> a = std::make_shared<ClassA>();
std::shared_ptr<ClassB> b = std::make_shared<ClassB>();
a->b = b;
b->a = a; // 循环引用
// 使用std::weak_ptr解决
std::shared_ptr<ClassA> a = std::make_shared<ClassA>();
std::shared_ptr<ClassB> b = std::make_shared<ClassB>();
a->b = b;
b->aWeak = std::weak_ptr<ClassA>(a);
内存池技术
- 原理:内存池预先分配一块较大的内存空间,当需要分配内存时,直接从内存池中获取小块内存,而不是每次都调用系统的内存分配函数(如
new
)。当释放内存时,将小块内存归还内存池,而不是直接释放给系统。
- 实现示例:
class MemoryPool {
char* pool;
size_t poolSize;
size_t blockSize;
char* freeList;
public:
MemoryPool(size_t poolSize, size_t blockSize)
: poolSize(poolSize), blockSize(blockSize) {
pool = new char[poolSize];
freeList = pool;
for (size_t i = 0; i < poolSize - blockSize; i += blockSize) {
reinterpret_cast<char**>(pool)[i / blockSize] = pool + i + blockSize;
}
reinterpret_cast<char**>(pool)[(poolSize - blockSize) / blockSize] = nullptr;
}
~MemoryPool() { delete[] pool; }
void* allocate() {
if (freeList == nullptr) return nullptr;
void* result = freeList;
freeList = *reinterpret_cast<char**>(freeList);
return result;
}
void deallocate(void* ptr) {
*reinterpret_cast<char**>(ptr) = freeList;
freeList = reinterpret_cast<char*>(ptr);
}
};
可能遇到的问题及解决方案
- 内存泄漏:
- 问题:智能指针使用不当,如忘记在合适的地方释放对象,或者循环引用导致对象无法释放。
- 解决方案:仔细检查智能指针的作用域和引用关系,使用
std::weak_ptr
解决循环引用问题。
- 性能瓶颈:
- 问题:内存池分配和释放算法不合理,导致内存碎片或者分配释放时间过长。
- 解决方案:优化内存池算法,例如采用更高效的空闲链表管理,或者使用不同大小的内存块来适应不同的对象需求。
- 野指针:
- 问题:指针初始化不当,或者对象提前释放导致指针悬空。
- 解决方案:严格遵循指针初始化策略,使用智能指针代替原始指针,确保对象生命周期得到正确管理。