C 什么时候程序可以使用内存?

C 什么时候程序可以使用内存?,c,pointers,C,Pointers,我有这两个程序只是为了理解指针是如何工作的。第一个名为test.c,下面是代码 #include <stdio.h> #include <stdlib.h> int main(void) { int *mem = malloc(sizeof(int) * 1); *mem = 90; //free(mem); printf("%p", mem); return (0); } 在第二个程序中,从命令行获取输入,然后将其更改为指针(地址)。它假定传递的是

我有这两个程序只是为了理解指针是如何工作的。第一个名为
test.c
,下面是代码

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int *mem = malloc(sizeof(int) * 1);
*mem = 90;
//free(mem);
printf("%p", mem);
return (0);
}
在第二个程序中,从命令行获取输入,然后将其更改为指针(地址)。它假定传递的是十六进制字符串。它所做的只是打印传递的内存地址,然后尝试获取该地址的值

接下来,我使用gcc(我使用linux)将每个文件编译为
test
test1
,并运行以下命令
/test | xargs./test1
,这会给我以下错误
xargs:./test1:由信号11终止。我知道这是因为test1引发了分段错误,因为如果我不尝试取消引用指针,我不会得到这个错误。但我不明白为什么我会出现seg故障。即使在释放内存后(在第一个程序中取消注释),我仍然会遇到分段错误。我希望得到一些垃圾值,而不是seg错误。我正在开始整个过程和指针的事情,所以肯定有什么我遗漏了,我希望有人会解释或指导我的资源

请重复我的问题,一个程序如何在不分配特定内存的情况下访问它呢?

你不能

内存地址分为页(通常为4096字节)。当您访问一个地址时,CPU在进程的“页面表”中查找带有该地址的页面。此表显示了该地址在物理内存中的位置(即“哪个RAM芯片”)

因此,您无法访问不在进程页表中的地址。句号

如何将页面添加到页面表中?你问操作系统。在Windows上,该函数称为
VirtualAlloc
。在Linux上,它被称为
mmap
。或者,您可以使用类似于
malloc
的函数,该函数只允许分配页面的一小部分(通过拆分从操作系统获取的页面)

此外,每个进程都有不同的页表。所以地址在不同的过程中意味着不同的东西。也许
test
进程可以为页面0x12345000创建一个页面表条目,但是
test1
进程没有,因为它们是完全不同的表。这就是为什么将指针从一个进程发送到另一个进程是没有意义的

在旧的计算时代,没有页表,指针是实际的RAM地址,但那些日子早已过去


编辑:您也可以要求操作系统同时将同一页放在两个不同进程的页表中,这称为共享内存。

因此,如果我了解您在做什么,您可以打印一个程序中动态分配的内存块的地址,并将其剪切和粘贴为第二个程序的输入,然后尝试访问该地址

这不起作用的原因有几个

首先是user253751指出的——地址不会跨不同的进程映射<进程A中的code>0x1234
映射到与进程B中的
0x1234
不同的物理内存单元。有几种方法可以在运行的进程之间设置共享内存,但这比这要复杂一些

其次,你使用了错误的类型。
int
不够大,无法存储指针值-在将
strtol
的结果强制转换并分配给
num
之后,您肯定丢失了一些数字,因此将其强制转换回指针将无法获得正确的地址


stddef.h
中的类型
intptr\u t
uintptr\u t
都是足够大的整数类型,可以存储指针值,但是它们的实现是可选的,而且还不能肯定
strtol
是否能够准确地转换输入值。

尽管用户253751给出了很好的技术解释,我想让它更适合初学者: 您的操作系统确保一个进程无法访问另一个进程的内存,因为这意味着您可能会操纵或破坏其他程序或窃取其数据(例如,密码)。
C语言不检查指针,所以你可以将它们设置为任何你想要的,但是如果你想访问这个地址,操作系统会阻止你,因为它有安全功能。

:哦,看,我的web应用程序刚刚扫描了所有内存,因为所有程序都可以看到70年代操作系统中的所有内存,并且找到了一些属于超级机密应用程序的内存。让我们玩得开心点……在PC上,您的程序只能访问某个特定的地址范围,而且无论如何,它们不是物理地址,范围可能会从一次运行到下一次运行。如果你从一个程序中获取一个地址并尝试将其放入另一个程序中,那是完全没有用的(出于设计)。@MichaelDorgan太糟糕了,我不是70年代出生的人,从事原始GameBoy游戏。这是一个系统,上面所说的将起作用…@MichaeldOrgang cool,这是非常深刻的。我不知道,在学习了指针之后,我想制作一个程序来读取内存中的每一位内容好的,谢谢。谢谢你所有的课程,我会读更多关于你提到的东西。好的,谢谢。我通过问这个问题了解了虚拟分配,谢谢大家。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
int num = (int)strtol(argv[1], NULL, 16);
int *mem = (void *)(long)num;

printf("at test1 string> %s, changed to pointer-->%p, after being dereferenced-->%i\n",argv[1], mem, *mem);
return (0);
}