Bruce_N 2023-06-03 06:35 采纳率: 55.6%
浏览 63
已结题

使用VS2019和Dev c++按%p输出地址,结果相差很大

int main()
{    
    char ch1, ch2;
    printf("ch1 = %p, ch2 = %p", &ch1, &ch2);
    return 0; 
}

同样的上述这段代码,很Dev c++运行的输出结果如下:

img


用vs2019运行结果如下:

img

Dev c++的运行结果能理解,不理解为什么vs2019运行结果两个字符变量的地址相差这么多,求专家解释

  • 写回答

8条回答 默认 最新

  • 「已注销」 2023-06-03 09:21
    关注

    引用chatgpt部分指引作答:
    在C语言中,使用"%p"格式说明符来打印指针地址是合法的。然而,输出的地址值可能因为编译器、操作系统和运行环境的不同而有所差异。

    对于你提供的代码,根据输出结果可以看出,在Dev C++中,ch1和ch2的地址是连续的,地址之间相差1个字节。而在VS2019中,这两个地址相差了6个字节。

    这种差异是由于编译器和内存对齐方式的不同引起的。内存对齐是指变量在内存中的存储方式,为了提高内存访问的效率,变量通常会被对齐到特定的内存地址上。对齐规则可能因编译器和操作系统而异。

    在Dev C++中,可能使用了默认的对齐方式,即按照变量的实际大小进行对齐。因此,连续声明的两个字符变量在内存中被分配了相邻的地址。

    而在VS2019中,可能使用了一种较为严格的对齐方式,即按照较大的数据类型进行对齐。在这种对齐方式下,两个字符变量之间被填充了额外的空间,以确保对齐到8字节边界(在这种情况下)。

    这种对齐方式的差异导致了输出结果中地址的差异。在实际应用中,这种差异通常不会对程序的正确性产生影响,因为变量的地址和内存布局对程序的执行逻辑并没有直接的影响。

    如果你对于变量的地址布局有特定要求,可以查阅编译器的文档,了解如何控制内存对齐方式或使用特定的编译选项来实现特定的内存布局。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • 创意程序员 2023-06-03 09:07
    关注

    不同的编译器可能会使用不同的格式打印地址,地址一般是16进制,但会有长度方面的差异,体现在有没有保留前面的0。内存本就是随机分配的,相应的地址也不一样,与当前内存使用情况有关。图中两个内存地址相差其实并不大,去掉前面的0,剩余部分是两个相差不太大的值,因为不同编译器、IDE占用内存不一样,导致已使用内存不一样,不同时间内存碎片不一样,可分配的内存也不一样。

    评论
  • 少林and叔叔 2023-06-03 07:40
    关注

    由于你这里定义两个参数,这两个参数的地址是由操作系统随机分布的地址;
    因此你打印出来两个地址都是随机的。
    关于你说两种编译器编译出来的程序,打印地址存在不同,这是存在,因为是随机的,具体是什么地址,就看当前系统运行的状态了~
    不知道能明白不

    评论
  • qfl_sdu 2023-06-03 08:05
    关注

    给你举个例子:
    假设你要跟朋友出去玩,需要订酒店,假设从某程定了A酒店的两个大床房,房间号是206和208。你从某团上看到A酒店的更便宜,所以你退了某程上的房间,又重新定了两个大床房,这时候,你订的房间号就不一定还是206和208了,206和208可能已经被别人订走了。再者,如果你发现某团突然没房了,你又重新返回某程订房间,这时候订的房间也不一定会是206和208了。

    这个题目跟上面的例子是一个道理,A酒店相当于系统内存,206和208相当于ch1和ch2的内存地址(内存是用来存数据的,房间是用来住人的,房间号相当于 一个地址标记),你在vs中运行完后,再在devc中运行,分配给ch1和ch2的内存可能就是不同的,哪怕你在VS中重新运行,系统给它们分配的内存也可能是不一样的。
    ——————————————————————————————————
    归根结底,最终的原因是:分配给变量的内存地址是由系统随机分配的!!基本上次次都不同。

    评论 编辑记录
  • 急速光粒 2023-06-03 09:22
    关注

    很正常啊,不同的操作系统,32位和64位系统,差别肯定很大。

    评论
  • 码银 Python领域新星创作者 2023-06-03 09:31
    关注

    这个代码每次的运行结果可能不一样,因为动态分配的内存地址每次不一定相同。

    在第一次运行程序时,由于 ch1 和 ch2 没有被初始化,它们分别被分配到不同的内存地址上。在第二次运行程序时,由于 ch1 和 ch2 已经被分配了内存空间,它们将被分配到与上一次不同的内存地址上,除非它们被释放。

    因此,每次运行这个程序时,输出的结果可能不同,除非你在第一次运行程序后手动释放 ch1 和 ch2 的内存空间。

    需要注意的是,即使输出的结果不同,这个程序也不会崩溃或出错,因为不同的内存地址不会互相干扰。这可能是因为两个编译器使用了不同的内存模型来输出地址。

    在 Visual Studio 2019 中,编译器默认使用了 (/GS) 选项,该选项启用了一个名为“GS寄存器”的安全缓冲区溢出检查。当 (/GS) 选项启用时,地址输出格式将发生变化,以包含 GS 标记。因此,使用 %p 格式化输出地址时,会在地址前面加上“\u”前缀以表示 GS 标记。

    而 Dev-C++ 编译器默认使用了 (/Stp) 选项,该选项启用了堆栈保护功能。当 (/Stp) 选项启用时,地址输出格式也会发生变化,以包含一个额外的冒号分隔符,表明该地址是在堆栈上分配的。

    因此,如果你使用 %p 格式化输出地址时,可能会在地址前面加上不同的前缀或分隔符,导致输出结果不同。为了确保正确比较地址,你可以使用 %Xp 格式化输出,该格式可以忽略 GS 和堆栈保护标记,以显示完整的地址值。

    评论
  • 四海一叶秋 2023-06-03 10:17
    关注

    两个编译器,你一个编译了64位的exe(devcpp),一个编译了32位(vs2019)?

    评论
  • xdh666666 2023-06-03 13:11
    关注

    ch1,ch2这两个地址不需要连续

    评论
查看更多回答(7条)

报告相同问题?

问题事件

  • 系统已结题 6月11日
  • 已采纳回答 6月3日
  • 创建了问题 6月3日

悬赏问题

  • ¥15 关于PROCEDURE和FUNCTION的问题
  • ¥100 webapi的部署(标签-服务器)
  • ¥20 怎么加快手机软件内部计时的时间(关键词-日期时间)
  • ¥15 C语言除0问题的检测方法
  • ¥15 为什么四分管的内径有的是16mm有的15mm,四分不应该是12.7mm吗
  • ¥15 macos13下 ios交叉编译的问题
  • ¥15 bgz压缩文件怎么打开
  • ¥15 封装dll(引入了pcl的点云设计库)
  • ¥30 关于#开发语言#的问题:我需要在抄板的基础上再抄板抄程序,根据RDA8851CM基础上开发
  • ¥15 oracle 多个括号,怎么删除指定的括号及里面的内容?