C语言深度感悟之内存溢出

由变量溢出所想到的

类型

比特(位)数

数值范围

[signed] int

16

-32768~32767(-2^15 ~ 2^15 – 1)

unsigned int

16

0 ~ 65535(0~2^16 - 1)

[signed] short int

16

-32768~32767(-2^15~2^15 - 1)

usigned short int

16

0~65535

long [int]

32

-2147483648 ~ 2147483647(-2^31 ~ 2^31 - 1)

unsigned long int

32

0 ~ 4294967295(0~2^32 - 1)

 

float

 

32

有效数字

数值范围

6~7

-3.4*10^-38~3.4*10^38

double

64

15~16

-1.7*10^-308~1.7*10^308

long double

128

18~19

-1.2*10^-4932~1.2*10^4932

[signed] char

8

 

-128~127

unsigned char

8

 

0~255

一个char类型溢出的程序

#include<stdio.h>

 

int main()

{

         chara = -128;

         charb;

 

         b= a - 1;

 

         printf("%d\n",b);

 

         return0;

}

 

编译运行结果:

[root@localhost overflow]# gcc char.c

[root@localhost overflow]# ./a.out

127

由char类型的取值范围可猜想:一个unsigned int型变量a = 65535;那么a – 1 = 0;

检验如下:(如今的计算机unsigned int类型的范围为:0 ~ 2 ^ 32-1)

#include<stdio.h>

 

int main()

{

         unsignedint a = 4294967295;

         unsignedint b;

 

         b= a + 1;

 

         printf("%d\n",b);

 

         return0;

}

[root@localhost overflow]# gcc int.c

int.c: 在函数 ‘main’ 中:

int.c:5: 警告:这个小数常量仅 ISO C90 中是无符号的

[root@localhost overflow]# ./a.out

0

[root@localhost overflow]#

此处的警告

 

再试验一下一个unsigned int b = -1会输出什么效果:

#include<stdio.h>

 

int main()

{

         unsignedint a = -1;

 

 

         printf("%d\n",a);

 

         return0;

}

输出结果:

[root@localhost overflow]# gcc int.c

[root@localhost overflow]# ./a.out

-1

unsigned b=-1;理论上似乎不该有这样的初始化。printf出来的b=-1

 

我的推理过程

假设上面初始化合法,我们把-1的补码存储到内存中,因为我们标记内存地址为&b的数为无符号整形,所以断点监视时,监测出一个大数;(这个大数似乎跟内存存在一定的关系,而不仅是单纯的CPU字长)

当调用printf函数时,printf根据取到的数先对符号位进行判断,发现符号位为1,是负数,所以求出取出来的数的补码,得到-1;

假设上面的推理成立,即断点监视和printf有自己一套判断一个数的方法,尽管有些荒谬;

我重定义了个整形变量a并且超出了int的可表示范围发现了个问题:内存中的这个数似乎仅给它标记为int类型数据,并不检查范围,只是简单的计算a的补码,并存储起来,高位按0填充;

断点监视和printf时发现是个正数,直接输出这个值;

本想用第二个初始化推倒上面的假设,却没法得到矛盾。

 

从上面似乎可以得出:int和unsigned似乎不再是C语言中简单的2个字节了,而已经被CPU字长和内存所影响。(上述推理来自网络)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值