【问题标题】:What is the address of buf (the local variable in the main function)?buf(主函数中的局部变量)的地址是什么?
【发布时间】:2014-11-04 18:10:07
【问题描述】:

我在 C 课程中进行了编程练习,并遵循了以下问题:

buf(主函数中的局部变量)的地址是什么?以十六进制格式(0x 后跟 8 个“数字”0-9 或 a-f,如 0xbfff0014)或十进制格式输入答案。注意这里我们要的是 buf 的地址,而不是它的内容。

代码如下:

int main(int argc, char *argv[]) {

   while(1) {
       char  buf[1024] = {0};
       int r;
    ....

所以我运行gdb 并简单地将断点放在char buf[1024] 行并输入gdb

 p &buf

这给了我一个结果:0xbffff0f0

但是当我在这个测验中使用这个数字时,它给我的结果是这个值不正确。

我的问题是:这是 buf 变量的 (p &buf) 地址吗?或者如果没有,为什么不呢?

练习是在准备好 VirtualBox 的机器上进行的,所以我认为每个人都应该有相同的地址

【问题讨论】:

  • 对,就是buf的地址。不,该地址不能保证是0xbffff0f0(它在不同的计算机上可能不同;哎呀,它甚至可能因程序在同一台计算机上的不同运行而不同!)。如果你有一个测验问你这个问题,那么测验中可能有更多你没有说明的限制或假设。
  • 是的,p 打印一个表达式,&buf 是缓冲区的表达式。做那个测验的人是个白痴(除非他们把所有事情都搞定并使用确定性的实现),因为那个地址对于测验来说太脆弱了。它可以随时改变。
  • buf 已经是一个指针。你正在取它的地址。在 gdb 中使用 p buf 代替。
  • @JewelThief: buf 是一个数组,不是一个指针。
  • @JewelThief:在大多数情况下,数组衰减为指向其第一个元素的指针(知道它不知道的地方!)。当我们这样吹毛求疵时,我们并不是受虐狂或虐待狂,这对于理解什么是什么以及避免错误的概括至关重要。马虎的命名法和编码会导致错误。

标签: c pointers gdb memory-address


【解决方案1】:

没有正确的数字答案。地址可能会因时间而异。这是你说的编程练习。以下三个语句都给了我相同的地址。

printf ("0x%08x\n", buf);
printf ("0x%08x\n", &buf[0]);
printf ("0x%08x\n", &buf);

【讨论】:

  • 当然他们都给出了相同的地址。他们将始终提供相同的地址(在一次运行中)。它们可能在多次运行中有所不同,但在一次运行中它们都是相同的。
  • 在 64 位编译器上,8 个十六进制数字不足以打印地址。
  • "以下三个语句都给了我相同的地址。"听起来像是“这是我观察到的行为;其他人可能会观察到不同的行为”(这是结尾的“对我而言”部分稍微扭曲了陈述以产生误导)。
  • @2501:在 6.5.2.1 中隐含(“E1[E2] 等同于(*((E1)+(E2)))”,表示buf[0] 等同于*(buf + 0),等同于*buf。此外,6.2.5/20 要求数组是连续的。6.5.(6 和 9)/7 表示 int* p; 的行为与 int p[1]; 相同。6.5.9/6 表示“如果 [.. .] 两者都是指向同一个对象的指针(包括指向对象的指针和开头的子对象)”(这意味着&buf == &(buf[0]))。我认为这些都严格限制了我们提到的行为。
  • 打印指针值的正确方法是使用%p 格式。该格式需要void* 参数,因此应强制转换参数:printf("%p\n", (void*)buf); 省略强制转换可能有效,但在某些特殊系统上可能会失败。 %x 需要 unsigned int 类型的参数。使用带有指针参数的%x(或0x%08x)具有未定义的行为,并且在指针与unsigned int 大小不同的系统上可能会失败(例如我正在输入的系统)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
  • 2019-09-06
  • 2012-09-05
  • 1970-01-01
  • 1970-01-01
  • 2014-04-12
相关资源
最近更新 更多