MST

星途 面试题库

面试题:C++静态存储区变量与栈、堆变量的交互及注意事项

假设在一个C++项目中,既有在静态存储区定义的全局变量,又有在栈上的局部变量以及在堆上动态分配的变量。请描述这三类变量在不同函数调用、模块交互过程中的可见性、作用域和生存周期情况,以及可能出现的内存相关问题及如何避免。
40.4万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试

1. 全局变量(静态存储区)

  • 可见性:在整个程序中可见,只要包含定义该全局变量的头文件,其他模块就能访问。
  • 作用域:从定义处到文件结束,如果使用extern关键字声明,作用域可扩展到整个程序。
  • 生命周期:从程序开始执行时创建,到程序结束时销毁。
  • 内存相关问题
    • 命名冲突:不同模块定义相同名字的全局变量会导致链接错误。
    • 初始化顺序问题:多个全局变量之间的初始化顺序可能影响程序行为。
  • 避免方法
    • 为全局变量取有意义且唯一的名字,最好加上模块相关的前缀。
    • 对于有依赖关系的全局变量,在代码中明确初始化顺序,或者使用单例模式等方式延迟初始化。

2. 局部变量(栈上)

  • 可见性:仅在定义它的函数或代码块内可见。
  • 作用域:从定义处到所在函数或代码块结束。
  • 生命周期:当函数或代码块被调用时创建,执行结束时销毁,栈空间被释放。
  • 内存相关问题
    • 栈溢出:如果函数递归过深或者局部变量占用栈空间过大,可能导致栈溢出。
  • 避免方法
    • 优化递归算法,避免无限制递归。
    • 对于占用空间较大的局部变量,考虑将其定义为静态局部变量(存于静态存储区)或动态分配到堆上。

3. 动态分配变量(堆上)

  • 可见性:取决于指针的作用域,指针在哪个作用域内有效,通过指针访问的堆上变量在该作用域内就可见。
  • 作用域:取决于指针的作用域。
  • 生命周期:从调用new(或malloc)分配内存开始,到调用delete(或free)释放内存结束。
  • 内存相关问题
    • 内存泄漏:如果分配了内存但没有释放,就会导致内存泄漏。
    • 悬空指针:释放内存后,指针没有置为nullptr,继续使用该指针会导致未定义行为。
  • 避免方法
    • 使用智能指针(如std::unique_ptrstd::shared_ptr)来管理动态分配的内存,它们会在适当的时候自动释放内存。
    • 手动管理内存时,确保delete(或free)与new(或malloc)成对出现,释放内存后将指针置为nullptr