8、C++匿名对象和程序运行内存划分段
匿名对象
#include<iostream>
#include<unistd.h> // sleep
using namespace std;// 增加一个概念,匿名对象。只有我这一行会使用这个创建对象,别人不需要使用
// 也就是说这个对象的声明周期只有那么一行
class Person{
public:Person() {cout << "构造函数调用" << endl;}~Person() {cout << "析构函数调用" << endl;}
};int main() {Person(); // 匿名对象,调用完立即析构// 怎么证明声明周期只存在于这一行呢sleep(3); // 睡眠3秒钟Person p; // 普通对象return 0;
}
- 匿名对象只在当前行生效
- 也就是说明这个对象的声明周期仅仅只有一行
程序运行内存划分段
在程序运行过程中,内存通常被划分为几个不同的区域,每个区域负责存储不同类型的数据。下面是对栈(Stack)、堆(Heap)、**数据段(Data Segment)和代码段(Code Segment)**的详细解释:
栈(Stack)
- 存储内容:
- 局部变量(如函数内部定义的变量)
- 函数调用时的参数
- 返回地址(用于函数调用返回)
- 特点:
- 后进先出(LIFO)结构
- 自动分配和释放内存
- 空间较小,速度快
- 由编译器自动管理
堆(Heap)
- 存储内容:
- 动态分配的内存(如使用
malloc
、new
等分配的空间)
- 动态分配的内存(如使用
- 特点:
- 空间大但管理复杂
- 需要手动分配和释放(如
free
、delete
) - 生命周期由程序员控制,容易造成内存泄漏或碎片
数据段(Data Segment)
- 存储内容:
- 全局变量和静态变量(包括初始化和未初始化的)
- 细分:
- 已初始化数据段:存储已赋初值的全局/静态变量
- 未初始化数据段(BSS段):存储未赋初值的全局/静态变量
- 特点:
- 在程序加载时由操作系统分配
- 生命周期贯穿整个程序运行期
代码段(Code Segment)
- 存储内容:
- 程序的机器指令(即编译后的可执行代码)
- 特点:
- 通常是只读的,防止程序修改自身代码
- 所有线程共享这段内存
当然可以!下面是一道涵盖代码段、数据段、堆、栈、只读数据段等内存区域的综合题目,适合用于理解 C/C++ 程序的内存布局。
请看一下这道题目:分析以下 C 代码的内存分布
请阅读以下 C 语言代码,并回答每个变量或数据项存储在哪个内存区域(代码段、数据段、BSS段(不细分也可以称之为数据段)、堆、栈、只读数据段):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>int global_init = 10;
int global_uninit;
const char* const_str = "hello";void func(int param) {int local_var = 5;char local_arr[] = "world";char* heap_str = (char*)malloc(6);strcpy(heap_str, "coder");printf("%s %s %s\n", const_str, local_arr, heap_str);free(heap_str);
}int main() {func(global_init);return 0;
}
🧠 问题:
请指出以下每个变量或数据项所在的内存区域,并简要说明原因:
global_init
global_uninit
"hello"
const_str
param
local_var
local_arr
heap_str
"coder"
func
函数体的代码
✅ 参考答案与讲解:
编号 | 名称 | 所在内存区域 | 说明 |
---|---|---|---|
1 | global_init | 数据段(已初始化) | 全局变量,已初始化为 10,存储在数据段中 |
2 | global_uninit | BSS 段 | 全局变量,未初始化,存储在 BSS(Block Started by Symbol)段 |
3 | "hello" | 只读数据段(RO Data) | 字符串字面量,编译时确定,存储在只读数据段 |
4 | const_str | 数据段(已初始化) | 全局指针变量,初始化指向只读数据段中的 "hello" ,本身在数据段 |
5 | param | 栈(Stack) | 函数参数,作为局部变量压入栈中 |
6 | local_var | 栈(Stack) | 函数内局部变量,存储在栈中 |
7 | local_arr | 栈(Stack) | 局部数组,内容为 "world" ,存储在栈中 |
8 | heap_str | 栈(指针)+ 堆(数据) | 指针变量本身在栈上,malloc 分配的内存在堆上 |
9 | "coder" | 只读数据段(RO Data) | 字符串字面量,strcpy 将其内容复制到堆中,但字面量本身在只读段 |
10 | func 函数体 | 代码段(Text Segment) | 函数的机器指令存储在代码段中 |
🎯 总结要点:
- 全局变量:
- 初始化的 → 数据段
- 未初始化的 → BSS 段
- 局部变量 → 栈
- 字符串字面量 → 只读数据段
- 动态分配的内存 → 堆
- 函数代码 → 代码段