如何获取C语言中的地址?

如何获取C语言中的地址?,c,pointers,memory-address,C,Pointers,Memory Address,对此可能有一个非常简单的答案,但我就是看不出来 #include <stdio.h> int main(void) { int x = 0; printf("\n%d\n%d\n",x,&x); } #包括 内部主(空){ int x=0; printf(“\n%d\n%d\n”,x和x); } printf给出了0(x)和2293752(&x)。我试图找出一种方法来查看任何地址(&),并查看其中已存储的内容。这只是为了实验。有什么帮助吗?这将是指针解引用,它是*运算符

对此可能有一个非常简单的答案,但我就是看不出来

#include <stdio.h>

int main(void) {
int x = 0;
printf("\n%d\n%d\n",x,&x);
}
#包括
内部主(空){
int x=0;
printf(“\n%d\n%d\n”,x和x);
}

printf给出了0(x)和2293752(&x)。我试图找出一种方法来查看任何地址(&),并查看其中已存储的内容。这只是为了实验。有什么帮助吗?

这将是指针解引用,它是*运算符。但是,对于随机地址,您无法判断存储的数据的类型

#include <stdio.h>

int main(void) {
int x = 0;
printf("\n%d\n%d\n%d\n",x,&x,*(&x));
}

/* resulting output will be 0, some memory address, and 0 again */
#包括
内部主(空){
int x=0;
printf(“\n%d\n%d\n%d\n”,x,&x,*(&x));
}
/*结果输出将为0,一些内存地址,然后再次为0*/

假设您希望查看“原始”数据,并且您知道进程地址空间中的地址,您可以执行以下操作:

long x=<address>
printf("%x", *(int *)x);
长x=
printf(“%x”,*(int*)x);

您可能会发现,检查任意内存地址只会导致崩溃。

如果您想探索内存,我建议使用低级别的调试器,例如。

尝试这样做有很多问题,首先也是最重要的是,正如Wilson提到的,您真的不知道存储在那里的是什么

Wilson有点不对劲,但是,你真的应该把它转换成一个字符而不是一个int,因为对于int,你会看到4个字节,而不是一个单独的字节

此外,除非您能够读取8位ASCII字符并将其映射到您头脑中有意义的内容,否则您可能希望将其转换为其他形式,例如base2、base8或base16

您可以通过几种方式来实现这一点-最好的方式可能是使用位运算符和二进制移位运算符,查找分派表以将其映射到可见的ASCII

然而,您仍然不知道它存储在那个里的是什么,您只能看到原始二进制数据的一些编码形式。原因是C的类型仅与指向该内存地址的变量有关。一个裸体的内存视图只会给你二进制文件,没有能力查找内存绑定的变量或者这些变量是什么类型的

第二个问题是,您需要小心,不要只查看您可以访问的内存部分。除非您对如何访问它非常小心,否则无法查看内存中的代码段。如果你四处寻找以避免分割错误,你将是幸运的

不过,查看进程内存的最有效方法可能是将其段转储到磁盘。在UNIX中,这是通过核心转储完成的。然后,您可以在调试器上加载它,查看您的核心内容,甚至可以将它映射到具有足够堆栈知识的正确类型。您还可以使用二进制编辑器以非类型化的方式对其进行检查-字符串通常是可识别的


祝你好运

要查看地址,可以使用%p

printf("%p",&x);
我建议您开始阅读指针,指针是存储内存地址的变量

int x=10;
int *p; //this is a pointer to int
p=&x; //now p has the memory location of x
printf("%d\n",*p); //this will print 10

我建议你用%p代替%d。它提供十六进制地址。%p代表
void*
,因此需要强制转换。顺便说一句,该标准并不保证它将以十六进制打印。不,它不保证,但我还没有被一个不保证的实现绊倒。当然,现代原生PDP-11C编译器可能会选择八进制,因为八进制是PDP-11上所有内容的自然表示形式。然而,我使用的PDP的上一个本机C编译器(DECUS C)太旧了,没有%p。您能解释一下这部分吗:*(int*)x-1:整数和指针在C:AFAIK中确实是不同的类型。不能保证
long
可以保存地址,而且我认为使用指针更为明确。Bastien:touché。事实上,这段代码非常依赖于硬件。真的没有一种便携的(安全的)方式来满足原始海报的需求。akway:*(int*)x将变量x转换为指向整数的指针,然后检索存储在该指针指向的位置的(整数)值。它有效地将x的值视为指向整数的内存地址,并读取该整数。如果该地址在进程的地址空间之外,它将失败(以依赖于环境的方式)。这不是我的意思。如果2293752是x的地址,那么我想检查地址0000000..9999999处的内容。请注意,*(&x)实际上将*运算符应用于值(&x)。您可以将其应用于不涉及&运算符的内容—例如,常量地址。您可以发现GCC在运行时中止程序。在这些情况下,它是非常严格的,所以你最好先使用适当的
%p
并强制转换为
void*
。同意-不管怎样,随机使用内存通常不是很有效。再次假设内存是一个int。对它进行了测试,是的,它只是崩溃了。我真的不需要知道任何地方都有什么,我只是好奇。你假设memAddr包含一个int,即4字节。您至少应该使用无符号整数,因为您同样可能使其显示为负数。将字符转换成可读格式(如十六进制)更为合理。地址可以包含任何内容,也可以转换为任何内容。例如:假设memAddr包含一个无符号字符,即一个字节。您至少应该使用带符号的字符,因为它实际上可能是负数。将int转换为一些可读格式(如decimal)更为合理。
int x=10;
int *p; //this is a pointer to int
p=&x; //now p has the memory location of x
printf("%d\n",*p); //this will print 10