并且如何知道哪一块内存大小是可以读可以写,以避免出现下面程序的 Segmentation Fault 呢?
```c
#include<stdio.h>
int main(){
        int *p = (int *)0x1;
    printf("%p\n", p);
    *p = 1;           // segmentation fault
    printf("%d", *p); // segmentation fault
}

```
举报· 193 次点击
登录 注册 站外分享
16 条回复  
iOCZS 小成 2024-3-20 20:40:23
是虚拟的,每个进程都有自己的虚拟地址空间,范围从 0x000'0000000 到 0x7FF'FFFFFFFF 。
内存里放着很多的段,像代码段被设置为只读的话,你去写入就会段错误。
proxytoworld 初学 2024-3-20 20:44:52
有 api 读取内存的属性
llh880808 小成 2024-3-20 20:53:29
1. c 语言中打印指针的值打印的是 OS 分配的虚拟地址的值吗?
是的,应用程序看到的地址都是虚拟地址
2. 要怎么知道 OS 给这个 c 程序进程分配的虚拟地址的大小呢?
每一个应用都会分配到整个物理内存大小的虚拟内存
3. 如何知道哪一块内存大小是可以读可以写?
使用更高特权等级(默认的 user 等级应该是无权访问的),查询 PMP 相关配置可以拿到内存地址的读写权限
BeiChuanAlex 小成 2024-3-20 22:48:50
你有没有想过把这个转成汇编,汇编基本上一目了然
yanqiyu 小成 2024-3-20 22:57:31
@llh880808 #3
> 每一个应用都会分配到整个物理内存大小的虚拟内存
并不准确,分配的空间大小和物理内存大小没关系。精简点的程序的用户地址空间甚至可能就只有程序和动态库的映射+自己的栈,花哨点的可以上来就要 TB 量级的匿名 mmap 自己分配。

> 使用更高特权等级(默认的 user 等级应该是无权访问的),查询 PMP 相关配置可以拿到内存地址的读写权限
其实可以读自己的 maps 文件/smaps 文件来查询(怎么看怎么不清真)
或者想办法直接干了然后捕获 SIGSEGV 就知道是不是可读可写了...
gcl123 小成 2024-3-20 23:28:28
进入 x86 实模式,就能打出实际内存地址了
chouxw112233 小成 2024-3-20 23:52:53
1. 虚拟地址
2. 不知道,否则函数传递数组,被退化指针,也不需要额外再传一个 size 了
3. 不是你申请出来的,就是不可以读写的,即使读写不出现 segfault ,也会很危险
leonshaw 小成 2024-3-21 00:10:55
linux 的话读 procfs 里的 maps
dangyuluo 小成 2024-3-21 03:37:07
可以通过读某个寄存器的值再进行对比来获得 stack 已用的大小,至于 heap 的大小的话忘了,用`brk`和`sbrk`的值来判断?
12下一页
返回顶部