int main(){
int value = 25;
int *pointer = &value;
printf("value = %d\n",value);
printf("pointer = %p\n",pointer);
printf("&pointer = %p\n",&pointer);
当我执行这个程序时,它打印值 25,0xbffff834
对于指针和0xbffff830
对于&指针。但是,当我使用 GDB 调试该程序并输入 break 6
时(指行 printf("value" = %d",value);
)并输入 print pointer
,GDB 给我结果 0xbffff824
。它还给了我 0xbffff820
当我输入print &pointer
时。调试器给出的地址和程序打印的地址不应该是相同的吗?如果不必如此,您能解释一下为什么不这样做吗?当我输入x/d pointer
时对于调试器,它给了我 25 (顺便说一下,这是正确的)。我的问题不是为什么 pointer
和&pointer
不同,这就是为什么当我使用命令 pointer
运行程序时,相同的指针(在本例中名为 ./deneme
的指针)存储不同的地址。 (我的程序的名称是deneme,当我使用gdb调试器调试该程序时。我使用命令gcc -g -o deneme deneme.c
来编译我的程序。该程序在调试器和使用顺便说一下 ./deneme
。
最佳答案
首先回答你的问题:
Shouldn't the adresses that the debugger gives and the program prints be the same?
答案是肯定的,他们应该这样做。这是合理调试的要求。
然而,在实践中,有时事情可能会出错。例如,如果您的程序依赖于未定义的行为,那么您可能会遇到编译器执行一件事(例如,采用分支)但调试器报告其他内容(打印条件表明它显然不应该采用)的情况分支)。造成差异的另一个原因是编译器错误。或者导致代码明显无序执行的优化(即,您可能会在预期之前或之后看到变量的值发生变化)。
正如评论者指出的,这里最有可能发生的是地址空间随机化(“ASLR”)。这是一项安全功能,内存布局在每次运行时都会发生变化。 gdb 默认情况下禁用此功能,但在大多数系统上,它在 gdb 之外默认启用。因此,例如,当我在控制台上尝试您的程序时,我会看到每次运行都有不同的指针值:
$ ./q
value = 25
pointer = 0x7ffc7797716c
&pointer = 0x7ffc77977160
$ ./q
value = 25
pointer = 0x7ffd77b8199c
&pointer = 0x7ffd77b81990
因此,重要的是将 gdb 中的值与 gcc 中相同运行打印的值进行比较。这对我来说效果很好:
(gdb) b 8
Breakpoint 1 at 0x400542: file q.c, line 8.
(gdb) r
Starting program: /tmp/q
value = 25
pointer = 0x7fffffffd8fc
&pointer = 0x7fffffffd8f0
Breakpoint 1, main () at q.c:8
8 }
(gdb) info local
value = 25
pointer = 0x7fffffffd8fc
(gdb) p &pointer
$1 = (int **) 0x7fffffffd8f0
在这里您可以看到值是相同的。
关于c - (gdb)print 指针和 printf ("%p",指针) 给出不同的地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50989915/