加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Linux > 正文

我在这里擦除堆栈吗?

发布时间:2020-12-13 23:53:56 所属栏目:Linux 来源:网络整理
导读:我正在 Linux上使用gcc,下面的代码编译成功,但没有正确打印变量i的值,如果一次输入一次字符我跳转或减少到0.我知道我在scanf使用%d作为字符(我试图擦除堆栈).这是一个尝试擦除堆栈或其他东西的情况吗?(我想如果堆栈被删除,程序将崩溃). #include stdio.hin
我正在 Linux上使用gcc,下面的代码编译成功,但没有正确打印变量i的值,如果一次输入一次字符我跳转或减少到0.我知道我在scanf使用%d作为字符(我试图擦除堆栈).这是一个尝试擦除堆栈或其他东西的情况吗?(我想如果堆栈被删除,程序将崩溃).

#include <stdio.h>

int main()
{
    int i;
    char c;

    for (i=0; i<5; i++) {
        scanf ("%d",&c);
        printf ("%d ",i);
    }
    return 0;
}

解决方法

除了main的参数之外,堆栈上还有一个int和一个char.
假设sizeof(int)== 4并且只看一下i和c.

(              int i               )(char c )
[   0   ][   1   ][   2   ][ 3 (&i)][ 4 (&c)]

所以这实际上是没有argc和* argv的堆栈布局.
在这种情况下,我消耗的内存是c的四倍.
堆栈以相反的方向增长,所以如果你写一个大于char的东西到c,它会写入[4]并进一步向左,从不向右.所以[5]永远不会被写入.相反,你覆盖[3].
对于你写一个int到c和int比c大四倍的情况,你实际上写到[1] [2] [3] [4],只是[0]不会被覆盖,但是3 / int的4个内存将被破坏.

在大端系统中,i的最高有效字节将存储在[3]中,因此会被此操作覆盖.在小端系统上,最重要的字节存储在[0]中并将被保留.尽管如此,你以这种方式破坏你的筹码.

正如艾姆斯提到的那样并非总是如此.可能存在不同的效率对齐,或者因为平台仅支持对齐访问,因此在变量之间留下间隙.此外,只要编译器没有as-if规则所述的可见副作用,就允许编译器进行任何优化.在这种情况下,变量可以完美地存储在寄存器中,并且永远不会保存在堆栈中.但是许多其他编译器优化和平台依赖性可能使这种方式变得更加复杂.所以这只是最简单的情况,不考虑平台依赖性和编译器优化,也似乎是在你的特殊情况下会发生的一些细微差别.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读