设为首页
收藏本站
开启辅助访问
全部
问与答
创意
技术
酷工作
生活
交易
资源
节点
飞墙
Follow
明白贴
影视
报酬
登录
注册
飞社-令人惊奇的创意工作者社区-
›
首页
›
React
›
c 语言中打印指针的值打印的是 OS 分配的虚拟地址的值吗 ...
FSHEX=FIND+SHARE+EXPRESS
飞社-令人惊奇的创意工作者社区- 是一个关于发现分享表达的地方
现在登录
没有账号?
立即注册
推荐主题
›
社保缴纳基数引发的讨论,表示理解不了
›
车牌摇到号了,无奈手头不宽裕,纠结是买二
›
去马来西亚做计算机靠谱吗?
›
最终还是对开发者下手了🤣
›
公司开始主动补缴社保了,是有什么大雷么?
今日热议主题
手持 Mac mini M4 和 macbook pro 如何共享
有什么免费的恶意 IP 库吗?
求针对技术面试的英语教学或者外教
租房办公桌选成品,自己 DIY,还是一步到位
免费的 WireGuard 组网服务
有没有 typecho 的 CDN 鉴权插件?
go 语言里 defer 的位置
请教下, windows 有没有切换无线网卡 ip(
11 月 25 号 新开 88VIP 权益
以图会友第 23 期
c 语言中打印指针的值打印的是 OS 分配的虚拟地址的值吗?要怎么知道 OS 给这个 c 程序进程分配的虚拟地址的大小呢?
rookiemaster
· 2024-3-20 20:33:52 · 192 次点击
并且如何知道哪一块内存大小是可以读可以写,以避免出现下面程序的 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
}
```
举报
·
192 次点击
登录
注册
站外分享
微信扫一扫
QQ分享
微博分享
豆瓣分享
复制链接
显示全部
|
最早评论
16 条回复
17#
PTLin
小成
2024-3-21 10:55:32
给你解释一下为什么你的代码会发生 segmentation fault ,以加强你对整个体系的认识。
在 Linux 中,地址空间会被分成一系列的段,例如映射到可执行文件段,映射到共享库的段,匿名映射(通常被用于堆)的段,这一系列段由叫 vma 结构的集合组成。可以从 proc 文件系统对应进程号的 maps 文件看到。
对于 x86 来讲虚拟地址会通过页表进行地址映射。倘若在页表里地址对应的条目不存在将会引发 page_fault 中断。
在中断的处理过程内,由于你的地址 0x1 是用户地址所以跳转到了处理用户地址的函数 do_user_addr_fault 。
这个函数会查找这个地址是否属于某个 vma ,然而没有查询到,所以调用了 bad_area_nosemaphore 向这个进程发送了 SIGSEGV 信号。
16#
heguangyu5
小成
2024-3-21 10:54:30
过一遍一个可执行文件(ELF)是怎么被操作系统(linux kernel)加载并执行的,就很清楚了.
http://heguangyu5.github.io/my-linux/html/20-init_post.html
15#
4king
小成
2024-3-21 10:45:30
pmap 可以看进程内存分布,得到虚拟地址对照看就行
14#
sbldehanhan
小成
2024-3-21 10:29:56
你需要内存就向操作系统申请一片内存,它会告诉你可用的内存地址,使用完就把它释放掉,至于哪片内存可用,哪片不可用,那是操作系统的事。如果这件事由程序员自己做,那要操作系统干啥?再说,你管理的过来吗?到时候程序不得走一步崩两次?
13#
dhb233
小成
2024-3-21 10:10:19
如果是要好好写程序,指针就不应该随便乱用啊。。。指针只应该指向你知道大小的内存,并且是在编码阶段就能明确内存大小的内存。比如 malloc 的一块内存,你申请的时候是知道有多大的;栈上的一个变量,你应该知道变量的 sizeof ;一个给定长度的数组,最大就是数组的 size ;无论哪种,你在写代码的时候,都要知道这块内存有多大。
同样的,传递指针的时候,要么是一个结构体的指针,要么一定加一个长度参数。
你非要用一些骚操作来解决,可以直接捕获段错误的信号啊,没有段错误就是没越界。但是这个也仅代表你没有越分配内存的界。如果越界写到了其他数据结构,那还是没办法。
12#
MeePawn666
小成
2024-3-21 04:23:35
搜索 MMU ,你就都明白了
11#
geelaw
小成
2024-3-21 04:22:27
> C 语言中打印指针的值打印的是 OS 分配的虚拟地址的值吗?
不是,它打印的是这个指针的整数表示。没有要求指针的整数表示必须等于操作系统级别的虚拟地址。当然,最常见的实现里,指针的整数表示就是它指向的对象的内存位置的虚拟地址。
> 要怎么知道 OS 给这个 C 程序进程分配的虚拟地址的大小呢?
操作系统不给“C 程序”分配虚拟地址,“虚拟地址”的大小可能也不是你想要的那个答案。操作系统为每个进程提供虚拟内存,每个程序都以为自己占有全部寻址空间的虚拟内存,虚拟地址的大小和处理器有关。
有意义的问题是:一个进程如何知道自己的虚拟内存里有多少页是可读的、可写的、可执行的?这个问题无法从 C 语言的抽象层级回答,你需要操作系统的 API 。
> 并且如何知道哪一块内存大小是可以读可以写,以避免出现下面程序的 Segmentation Fault 呢?
在 C 语言看来,只有 malloc 等分配得到且未 free 、realloc 等的、取静态存储期对象的地址得到的、取自动存储期对象地址得到且该对象还未离开作用域的指针,以及它进行有定义算术运算得到的指针,才是有效的指针。解引用无效指针的效果是未定义行为,段错误仅仅是它的一种表现方式。
当然,结合操作系统 API 之后有更多获得有效指针的方式。但楼主本来的这个问题意义不明——如果你不知道一个指针怎么来的,使用它有什么意义呢?如果你知道一个指针怎么来的,那你当然知道这个指针是否有效。
10#
dangyuluo
小成
2024-3-21 03:37:07
可以通过读某个寄存器的值再进行对比来获得 stack 已用的大小,至于 heap 的大小的话忘了,用`brk`和`sbrk`的值来判断?
9#
leonshaw
小成
2024-3-21 00:10:55
linux 的话读 procfs 里的 maps
8#
chouxw112233
小成
2024-3-20 23:52:53
1. 虚拟地址
2. 不知道,否则函数传递数组,被退化指针,也不需要额外再传一个 size 了
3. 不是你申请出来的,就是不可以读写的,即使读写不出现 segfault ,也会很危险
下一页 »
1
2
/ 2 页
下一页
返回顶部