> C 语言中打印指针的值打印的是 OS 分配的虚拟地址的值吗?
不是,它打印的是这个指针的整数表示。没有要求指针的整数表示必须等于操作系统级别的虚拟地址。当然,最常见的实现里,指针的整数表示就是它指向的对象的内存位置的虚拟地址。
> 要怎么知道 OS 给这个 C 程序进程分配的虚拟地址的大小呢?
操作系统不给“C 程序”分配虚拟地址,“虚拟地址”的大小可能也不是你想要的那个答案。操作系统为每个进程提供虚拟内存,每个程序都以为自己占有全部寻址空间的虚拟内存,虚拟地址的大小和处理器有关。
有意义的问题是:一个进程如何知道自己的虚拟内存里有多少页是可读的、可写的、可执行的?这个问题无法从 C 语言的抽象层级回答,你需要操作系统的 API 。
> 并且如何知道哪一块内存大小是可以读可以写,以避免出现下面程序的 Segmentation Fault 呢?
在 C 语言看来,只有 malloc 等分配得到且未 free 、realloc 等的、取静态存储期对象的地址得到的、取自动存储期对象地址得到且该对象还未离开作用域的指针,以及它进行有定义算术运算得到的指针,才是有效的指针。解引用无效指针的效果是未定义行为,段错误仅仅是它的一种表现方式。
当然,结合操作系统 API 之后有更多获得有效指针的方式。但楼主本来的这个问题意义不明——如果你不知道一个指针怎么来的,使用它有什么意义呢?如果你知道一个指针怎么来的,那你当然知道这个指针是否有效。 |