面试题答案
一键面试全局变量
- 影响因素
- 动态链接库加载与卸载:如果全局变量在动态链接库中,当动态链接库被加载时,全局变量被初始化;当动态链接库被卸载时,全局变量被销毁。不同动态链接库加载和卸载的时机可能不同,这会影响全局变量的生命周期。
- 多线程访问:多个线程可能同时访问全局变量,若没有适当的同步机制,可能在全局变量初始化完成前就被其他线程访问,导致数据错误。
- 避免内存泄漏或数据错误的方法
- 使用单例模式:通过单例模式控制全局对象的创建和销毁,保证在整个程序生命周期内只有一个实例,并且可以在合适的时机进行初始化和销毁。
- 线程同步:使用互斥锁(
std::mutex
)等同步机制,确保在全局变量初始化完成前,其他线程不会访问。
代码示例:
#include <iostream>
#include <mutex>
class Singleton {
public:
static Singleton& getInstance() {
static std::mutex mtx;
static Singleton instance;
return instance;
}
// 防止拷贝和赋值
Singleton(const Singleton&) = delete;
Singleton& operator=(const Singleton&) = delete;
private:
// 私有构造函数
Singleton() = default;
~Singleton() = default;
};
// 假设这是一个在动态链接库中的全局变量
Singleton& globalVar = Singleton::getInstance();
void threadFunction() {
// 使用全局变量
Singleton& var = Singleton::getInstance();
std::cout << "Thread using global variable" << std::endl;
}
局部变量
- 影响因素
- 多线程栈空间:每个线程都有自己独立的栈空间。局部变量在栈上分配,如果一个函数在多线程环境下被调用,每个线程都有自己的局部变量副本,其生命周期与线程栈的生命周期相关。
- 动态链接库函数调用:如果在动态链接库函数内部定义局部变量,其生命周期受函数调用和返回的影响。如果函数返回后,局部变量所占用的资源没有正确释放,可能导致内存泄漏。
- 避免内存泄漏或数据错误的方法
- 使用智能指针:对于局部变量中的动态分配内存(如
new
操作符),使用智能指针(std::unique_ptr
、std::shared_ptr
)来管理内存,它们会在局部变量生命周期结束时自动释放内存。 - 确保资源释放:对于非内存资源(如文件句柄等),在函数结束前确保资源被正确关闭或释放。
- 使用智能指针:对于局部变量中的动态分配内存(如
代码示例:
#include <iostream>
#include <memory>
void dynamicLibraryFunction() {
// 使用智能指针管理动态分配的内存
std::unique_ptr<int> localPtr(new int(10));
std::cout << "Local variable value: " << *localPtr << std::endl;
// 局部变量localPtr生命周期结束时,内存自动释放
}