鱼C论坛

 找回密码
 立即注册
查看: 1619|回复: 5

栈的存储是怎样的?

[复制链接]
发表于 2023-4-4 18:53:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
代码如下:
#include<stdio.h>

int main()
{
        char c=0, a=0,b=0;
        int *p=(int *)&b;
        *p=256;
        printf("%d %d %d\n",c,a,b);


        return 0;
}//
为啥输出为:1,0,0
同样:
#include<stdio.h>

int main()
{
        char a=0,b=0;
        int *p=(int *)&b;
        *p=256;
        printf("%d %d %d\n",c,a,b);


        return 0;
}//为啥输出为:1,0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-4 18:55:53 | 显示全部楼层
这两个程序都包含了指针的类型转换和越界访问,导致输出结果与预期不符。具体解释如下:

第一个程序中,将整型指针p指向了变量b的地址,但b只有一个字符大小,因此指针p指向的内存空间越界了。接着,将p所指向的内存空间赋值为256,即在该内存空间写入了一个int类型的值,但由于该内存空间越界,可能会覆盖其他变量的值。最后输出了三个变量c、a、b的值,其中c和b都被修改过,而a没有修改,因此输出结果为1,0,0。

第二个程序中,与第一个程序类似,也将一个整型指针p指向了变量b的地址并进行了越界访问,写入了一个int类型的值256。然而这里没有定义变量c,编译器会自动将其初始化为0。最终输出了三个变量c、a、b的值,其中c的初始值为0,b被修改过,而a没有修改,因此输出结果为1,0,0。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-4 18:56:53 | 显示全部楼层
栈的存储是一种后进先出(LIFO)的数据结构,用于在程序中存储局部变量、参数、返回地址等。栈是向低地址方向增长的。

对于这两段代码,我们先分析第一个代码段。在这段代码中,定义了三个字符变量c、a、b,分别初始化为0。接着,你创建了一个指向b的整数指针p,然后将整数256写入*p。由于b的类型是char,它只能存储1个字节的数据(范围为-128到127,或0到255),所以将整数256存储到b中会导致溢出。整数256的二进制表示为0000 0001 0000 0000,将其存储到一个char类型的变量中时,低8位被截断,只保留高8位。因此,b的值将为0,而a的值将变为1(高8位的数据)。

在第二段代码中,你移除了变量c,这导致a和b在栈上的相对位置发生了变化。当你再次执行类似的操作时,依然会导致溢出,但这次是a的值变为1,而b的值保持为0。

输出的原因在于内存中变量的存储顺序和栈的增长方向。在这种情况下,a和b在栈上的相对位置发生了变化,从而导致了不同的输出结果。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-4 19:08:28 | 显示全部楼层
isdkz 发表于 2023-4-4 18:56
栈的存储是一种后进先出(LIFO)的数据结构,用于在程序中存储局部变量、参数、返回地址等。栈是向低地址方 ...

小甲鱼说的是:栈是由高地址往低地址发展;堆则相反;这确实是栈为啥是从低地址开始发展的呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-4 19:11:27 | 显示全部楼层
年,兮 发表于 2023-4-4 19:08
小甲鱼说的是:栈是由高地址往低地址发展;堆则相反;这确实是栈为啥是从低地址开始发展的呢?


栈是从高地址向低地址发展,而堆是从低地址向高地址发展。

栈从高地址向低地址发展的原因主要与计算机内存的组织方式和系统调用栈的设计有关。

  • 内存分配策略:在大多数操作系统中,栈和堆位于不同的内存区域。栈通常位于高地址空间,而堆位于低地址空间。

    这种设计策略有助于提高内存利用率,因为栈和堆可以相互靠近,共享可用的内存空间。

    这种设计方式使得栈和堆在内存中可以自由地扩展,只要它们没有相互碰撞。

  • 系统调用栈:操作系统在处理系统调用时,会为每个调用创建一个栈帧,其中包含函数参数、局部变量和返回地址。

    这些栈帧通常以后进先出(LIFO)的顺序存储,因此栈从高地址向低地址发展。

    这种设计有助于保持栈帧的连续性和内存访问的局部性,从而提高性能。


这些设计原则是为了提高内存管理效率、简化内存分配和释放过程以及保持栈帧的连续性。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-4 19:45:41 | 显示全部楼层
盒子装东西先进后出,后进先出
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-9-21 11:17

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表