C++ 堆、栈、静态区:变量到底存在哪?

C++ 堆、栈、静态区:变量到底存在哪?

C++ 堆、栈、静态区:变量到底存在哪?

在这里插入图片描述

一、C++ 堆、栈、静态区:变量到底存在哪?

1、 栈(Stack)

  • 存储内容:主要用于存储函数的局部变量、函数参数、函数调用的返回地址等。每次函数调用时,系统会在栈上为其分配一块内存(称为“栈帧”),函数返回时自动释放。
  • 管理方式:由编译器自动管理,遵循“后进先出”(LIFO)原则。分配和释放速度极快。
  • 生命周期:与函数调用的生命周期绑定。局部变量在函数开始时分配,函数结束时销毁。
  • 大小限制:通常有固定大小限制(由系统或编译器设置)。分配过大的局部变量(如超大数组)可能导致栈溢出(Stack Overflow)。
  • 访问速度:访问速度快,因为内存地址通常是连续的,且靠近 CPU 寄存器。

示例

voidmyFunction(){int a =10;// 局部变量 a 分配在栈上double b =3.14;// 局部变量 b 分配在栈上}// 函数结束,a 和 b 自动销毁

2、 堆(Heap)

  • 存储内容:用于存储动态分配的内存。程序在运行时显式请求分配(如使用 newmalloc)和释放(如使用 deletefree)的内存块。
  • 管理方式:由程序员手动管理(或通过智能指针等机制辅助管理)。分配和释放相对较慢。
  • 生命周期:从分配时刻开始,直到显式释放为止。如果忘记释放(内存泄漏),该内存会一直占用直到程序结束。
  • 大小限制:通常受系统可用物理内存和虚拟内存的限制,比栈大得多。
  • 访问速度:访问速度相对栈慢,因为需要通过指针间接访问,且内存可能不连续。

示例

voiddynamicAlloc(){int* ptr =newint(100);// 在堆上分配一个 int,初始化为 100// ... 使用 ptr ...delete ptr;// 必须手动释放,否则内存泄漏}

3、 静态区(Static Storage Area)

  • 存储内容:存储全局变量、静态局部变量(用 static 修饰的局部变量)、静态成员变量以及常量(如字符串字面量)。程序开始运行时分配,结束时释放。
  • 管理方式:由编译器在程序启动前分配,程序结束时由系统回收。
  • 生命周期:整个程序的运行期(全局生命周期)。
  • 初始化:未显式初始化的全局/静态变量会被自动初始化为零(或空指针)。
  • 线程安全:C++11 后,静态局部变量的初始化是线程安全的。

示例

int globalVar =5;// 全局变量,在静态区voidfunc(){staticint count =0;// 静态局部变量,在静态区,只初始化一次 count++;}classMyClass{public:staticint s_value;// 静态成员变量声明};int MyClass::s_value =10;// 静态成员变量定义(在静态区)

4、 对比总结

特性栈 (Stack)堆 (Heap)静态区 (Static)
管理方式编译器自动管理 (LIFO)程序员手动管理 (new/delete)编译器管理 (程序启动分配,结束释放)
生命周期函数调用期间newdelete整个程序运行期
大小较小 (固定)较大 (受系统内存限制)编译时确定
速度快 (连续内存)慢 (需寻址)快 (固定地址)
主要用途局部变量、函数参数、返回地址动态分配的对象全局变量、静态变量、常量
风险栈溢出内存泄漏、野指针初始化顺序问题

5、 使用建议

  1. 优先使用栈:局部变量尽量在栈上分配,安全高效。
  2. 谨慎使用堆:动态内存需确保配对释放。推荐使用智能指针(如 std::unique_ptr, std::shared_ptr)管理堆内存,避免手动 delete
  3. 合理使用静态区:全局变量和静态变量需注意初始化顺序和线程安全问题(C++11 后静态局部变量是线程安全的)。避免滥用,尤其是跨文件的全局变量。

二、示例

#include<iostream>// 全局变量 - 存储在静态区(数据段)int global_var =100;voidfunctionWithStatic(){// 局部静态变量 - 存储在静态区(数据段)staticint static_var =0; static_var++; std::cout <<"静态变量 static_var 的值: "<< static_var << std::endl;}intmain(){// 栈变量 - 存储在栈上int stack_var =10; std::cout <<"栈变量 stack_var 的值: "<< stack_var << std::endl;// 堆变量 - 存储在堆上(手动分配)int* heap_var =newint(20); std::cout <<"堆变量 *heap_var 的值: "<<*heap_var << std::endl;// 访问全局变量 std::cout <<"全局变量 global_var 的值: "<< global_var << std::endl;// 调用函数展示静态变量functionWithStatic();// 输出: 静态变量 static_var 的值: 1functionWithStatic();// 输出: 静态变量 static_var 的值: 2// 必须手动释放堆内存delete heap_var; heap_var =nullptr;return0;}

运行结果:

栈变量 stack_var 的值:10 堆变量 *heap_var 的值:20 全局变量 global_var 的值:100 静态变量 static_var 的值:1 静态变量 static_var 的值:2 C:\Users\徐鹏\Desktop\新建文件夹\Project1\x64\Debug\Project1.exe(进程 30784)已退出,代码为 0(0x0)。 要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。 按任意键关闭此窗口...
在这里插入图片描述

代码说明:

  1. 栈存储 (stack_var):
    • main 函数内部声明。
    • 生命周期与其所在的作用域(main 函数)绑定。当 main 函数结束时,它会被自动销毁。
    • 内存分配和释放由编译器自动管理。
  2. 堆存储 (*heap_var):
    • 使用 new 运算符在堆上动态分配内存。
    • 需要程序员手动使用 delete 释放内存,否则会导致内存泄漏。
    • 指针 heap_var 本身是一个栈变量(存储着堆内存的地址)。
  3. 静态存储区:
    • 全局变量 (global_var): 在函数外部声明。它在整个程序运行期间都存在,在 main 函数开始执行前初始化,在程序结束时销毁。
    • 局部静态变量 (static_var):functionWithStatic 函数内部声明,但使用 static 关键字修饰。它只在第一次调用该函数时初始化一次,之后其值会保持,直到程序结束。虽然它在函数内声明,但其存储位置在静态区。
在这里插入图片描述

Read more

【MySQL数据库基础】(一)保姆级 MySQL 环境配置教程!CentOS 7+Ubuntu 双系统全覆盖

【MySQL数据库基础】(一)保姆级 MySQL 环境配置教程!CentOS 7+Ubuntu 双系统全覆盖

前言         作为后端开发、数据库学习的入门必备,MySQL 的环境配置是很多小伙伴的第一道 “小关卡”。尤其是不同 Linux 发行版(CentOS 7、Ubuntu)的安装步骤差异,再加上系统自带 MariaDB 的干扰、密码策略限制、中文编码等坑,很容易让人踩雷卡壳。         这篇博客就带来保姆级 MySQL 环境配置指南,不仅详细拆解 CentOS 7 下的完整安装步骤(从卸载冲突环境到配置优化),还补充了 Ubuntu 系统的安装流程,全程命令可直接复制,新手也能一步到位搞定 MySQL 环境,告别配置报错的烦恼!下面就让我们正式开始吧! 一、前置知识:为什么要先处理 MariaDB?         MySQL 被 Oracle 收购后,很多 Linux 发行版(比如 CentOS 7、

By Ne0inhk
【hacker送书第15期】AI绘画精讲与AIGC时代游戏美术设计:从入门到精通

【hacker送书第15期】AI绘画精讲与AIGC时代游戏美术设计:从入门到精通

文章目录 * 😊前言 * AI绘画精讲:Stable Diffusion从入门到精通💕 * 内容简介 * 获取方式 * AIGC时代:游戏美术设计与AI绘画应用从入门到精通💕 * 内容简介 * 获取方式 * 😊总结 😊前言 随着人工智能技术的飞速发展,AI绘画已经成为了一个备受瞩目的领域。在这个背景下,北京大学出版社推出了一系列关于AI绘画的优秀图书,其中就包括了《AI绘画精讲:Stable Diffusion从入门到精通》和《AIGC时代:游戏美术设计与AI绘画应用从入门到精通》。这两本书都是为了帮助读者全面了解和掌握AI绘画的精髓,推动人工智能技术在艺术领域的应用发展。 AI绘画精讲:Stable Diffusion从入门到精通💕 内容简介 Stable Diffusion是一款非常受欢迎的 AI 绘画与设计软件。AI绘画和传统绘画有什么不同、AI 绘画的基本逻辑是什么、如何让 AI 绘画软件为我们工作、如何生成符合要求的作品,本书将一一进行解析。 本书共 13 章内容。首先循序渐进地介绍了 A

By Ne0inhk

在普通电脑上跑大模型?!llama.cpp 实战指南(真·CPU救星)

文章目录 * 🤯 为什么你需要关注llama.cpp? * 🚀 手把手实战:十分钟跑通模型 * 第一步:准备战场环境 * 第二步:获取模型文件(关键!) * 第三步:启动模型交互! * 🛠️ 高级玩法解锁 * 💡 我的深度体验报告 * 👍 真香时刻 * 🤔 遇到的坑 * 🌟 超实用场景推荐 * 🔮 未来展望:CPU的逆袭? 还在为没显卡跑不动AI模型发愁?这个开源项目让我的旧笔记本起死回生了! 朋友们!今天要分享一个让我拍桌子叫绝的开源神器——llama.cpp。当初看到这个项目时我整个人都惊呆了:纯C++实现!不需要GPU!普通CPU就能跑! 作为一个常年被显卡价格PUA的程序员,这简直是救命稻草啊! 🤯 为什么你需要关注llama.cpp? 先说说我踩过的坑吧。去年想在家折腾开源大模型,结果: * 显卡要求动不动就16G显存(我的1060直接哭晕) * 装依赖环境能折腾一整天(Python版本地狱啊!) * 跑个7B模型风扇像直升机起飞(邻居以为我在挖矿) 直到发现了Georgi Gergan

By Ne0inhk

基于Llama-Factory的企业知识库问答系统构建

基于Llama-Factory的企业知识库问答系统构建 在企业数字化转型的浪潮中,员工对内部信息的即时获取需求正变得前所未有的迫切。想象这样一个场景:一名新入职的员工想了解年假申请流程,他不再需要翻找长达几十页的制度文档,也不必反复追问HR同事,而是直接在企业IM工具里问一句:“我怎么申请年假?”——系统立刻给出清晰、准确的操作指引。 这背后,正是大语言模型与企业私有知识深度融合的结果。然而,通用大模型虽然“博学”,却对企业内部规则“一无所知”。如何让AI真正理解组织的“专属语言”?微调(Fine-tuning)成为关键路径。但传统微调动辄需要多卡A100、数周训练周期和专业算法团队支持,对大多数企业而言门槛过高。 直到像 Llama-Factory 这样的开源框架出现,局面才被彻底改变。它把复杂的模型定制过程封装成可配置、可视化的流水线,使得单张消费级显卡也能完成领域模型的训练。这意味着,即使是非算法背景的工程师,也能在几天内为公司打造一个“懂业务”的AI助手。 Llama-Factory 的核心定位是一个开箱即用的大模型微调集成环境。它不是某个单一技术的实现者,而是一个高度

By Ne0inhk