江小南

V1

2023/01/28阅读:18主题:萌绿

【C语言】内存溢出解析

阅读本文,需要对C语言的基础知识有所了解。C语言基础,我给大家准备了详细的学习资料,微信公众号主页回复“C语言”即可领取。

同时,你应当阅读了补码的知识:

小端存储与补码

1. 整型不同类型

整型变量包括6种类型。

类型 类型说明符
有符号基本整型 (signed)int
有符号短整型 (signed)short(int)
有符号长整型 (signed)long(int)
无符号基本整型 unsigned int
无符号短整型 unsigned short (int)
无符号长整型 unsigned long (int)

说明:括号内的在实际编码时可以不用写。

有符号与无符号整型的最高位代表的意义不同。

以short类型为例:

说明:对于有符号数,最高位是符号位,最高位是0表示正数,1表示负数。无符号数没有符号位。

2. 内存溢出

不同整型变量表示的整型范围如图所示,超出范围会发生内存溢出现象,导致计算出错。

思考:有符号短整型可以表示的最大值为32767,当我们对其加1时,b的值会变成多少呢?

#include <stdio.h>

int main() {
    short a=32767;
    short b=0;
    b=a+1// 发生了溢出,解决溢出的办法是用更大的空间来存
    printf("b=%d\n",b);  // b并不是32768
}
F:\Computer\Project\practice\20\20.4-overflow\cmake-build-debug\20_4_overflow.exe
b=-32768

进程已结束,退出代码为 0

说明:b并不是32768,而是-32768,结果出错了。

解析

3. 有符号与无符号对比

#include <stdio.h>

int main() {
    short b=0;
    unsigned short n=0x8056// 无符号类型,最高位不认为是符号位
    b=0x8056;
    printf("b=%d\n",b); // b是有符号类型,最高位是符号位,所以输出是负值
    printf("n=%u\n",n); // 无符号类型要用%u,用%d是不规范的
    return 0;
}
F:\Computer\Project\practice\20\20.4-overflow\cmake-build-debug\20_4_overflow.exe
b=-32682
n=32854

进程已结束,退出代码为 0

解析

总结

  1. 负数用补码表示,要得到原码,需要取反并加1。
  2. 0x8000是最小的short类型负数,即-32768。
  3. 发生了溢出,解决溢出的办法是用更大的空间来存。
  4. 其他类型依据short类型同样的方法可以得出结论。
  5. 无符号类型要用%u,用%d是不规范的

分类:

后端

标签:

C++

作者介绍

江小南
V1