普通指针无法读取系统内存状态,因c++指针仅限用户态虚拟地址空间,硬编码地址未映射会触发段错误或访问违例;合法方式是通过os接口获取进程或系统内存统计。

不能直接用普通指针读取系统内存状态——这是操作系统内核保护的禁区,C++ 指针只能访问当前进程的用户态虚拟地址空间,越界或访问非法地址会触发 SEGFAULT 或 ACCESS_VIOLATION。
为什么 char* p = (char*)0x7ffed000; *p 会崩溃
现代操作系统(Linux/Windows/macOS)启用 MMU 和分页机制,所有指针操作都经过虚拟地址翻译。硬编码物理地址(如 0x7ffed000)或内核地址(如 0xffff888000000000)在用户态完全无效;即使该地址在物理内存中存在,也未映射到当前进程页表,CPU 会在 TLB 查找失败后抛出异常。
- Linux 下触发
Segmentation fault (core dumped) - Windows 下触发
Access violation reading location 0x... - 即便用
mmap()映射设备内存(如/dev/mem),也需要 root 权限且默认被禁用(CONFIG_STRICT_DEVMEM=y)
真正可读的“系统内存状态”有哪些
用户态程序能合法获取的是**本进程内存使用快照**或**系统级统计摘要**,依赖 OS 提供的受控接口,不是裸指针遍历:
-
Linux:读取
/proc/self/status(当前进程)或/proc/meminfo(全局内存统计),用fopen()+fscanf()解析文本字段 -
Windows:调用
GetProcessMemoryInfo()(需#include <psapi.h></psapi.h>)获取PROCESS_MEMORY_COUNTERS结构体 -
跨平台方案:用
mallinfo()(glibc)或malloc_stats()粗略看堆状态,但不反映物理内存
示例(Linux 读 /proc/meminfo):
FILE* f = fopen("/proc/meminfo", "r");
if (f) {
char line[256];
while (fgets(line, sizeof(line), f)) {
if (strncmp(line, "MemAvailable:", 13) == 0) {
sscanf(line, "MemAvailable: %ld kB", &available_kb);
break;
}
}
fclose(f);
}
想读其他进程或内核内存?必须绕过用户态限制
这已超出 C++ 语言能力范畴,属于驱动/内核模块或调试器行为:
- Linux:需编写内核模块(用
copy_from_user()/remap_pfn_range()),或通过ptrace(PTRACE_ATTACH)配合process_vm_readv()(需目标进程同 uid 或 CAP_SYS_PTRACE) - Windows:需以管理员权限调用
OpenProcess()+ReadProcessMemory(),且目标进程未开启PROTECT_FROM_DEBUGGING - 所有方式都受 SELinux/AppArmor/AMSI/ETW 等安全策略拦截,普通程序无权执行
试图用 reinterpret_cast<uint8_t>(0xffff...)</uint8_t> 强转内核地址,在绝大多数发行版和 Windows 版本上会立即 crash,不是“读不到”,是根本没机会执行到解引用那步。
真正的难点不在语法怎么写,而在于理解“系统内存”不是一块可自由游走的数组——它是被页表、权限位、TLB、SMAP/SMEP 层层隔离的资源。任何绕过这些机制的尝试,都会在 CPU 级别被硬件拒绝。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











