别摸鱼啦,说的就是你,学习编程从入门到放弃。掌握编程思维方式,由浅至深,理解编程技术原理,积累知识,向往自由编程。
C/C++ 强制类型转换(基本数据类型)存在安全隐患的情况
第一种 涉及到指针
代码案例分析 1
下面一段代码中,使用了强制类型转换,将 unsigned int* 转换成了time_t* (long long int *)。虽然编译器并未报错,但是在实际的运行过程中存在了隐患,内存访问出现了内存越界。
gdb调试过程分析:
代码案例分析 2
示例代码
int timestamp_transition()
{
unsigned int timestamp = time(NULL);
/* time_t: long long int (8 byte) */
const time_t * tt = (const time_t *)(×tamp); /* 强制转换成 time_t* */
printf("[tt_addr:%p] [timestamp_addr:%p]\n", tt, ×tamp); /* 指向同一地址块 */
unsigned long long temp_1 = 0;
unsigned long long temp_2 = 0;
memcpy(&temp_1, ×tamp, sizeof(unsigned int)); /* 取4字节 */
memcpy(&temp_2, ×tamp, sizeof(time_t)); /* 取8字节 */
/* 以上代码 看起来没问题,但是精彩的来了: */
struct tm * time_info = ::localtime(tt); /* 这里就有意思了,强制转换后出现了内存越界/溢出,导致出错 */
char time_str[50] = {0};
cout << "time_info:" << time_info << endl;
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", time_info);
return 0;
}
[示例代码] 内存分析
图一 强制类型转换 内存示意图
第二种 非指针
对于非指针的强制类型转换,分为向上、向下类型转换,解释如下:
向上强制类型转换
int:4字节,long long int:8字节,由int 类型转换到 long long int 类型,类似于这种的基本变量类型转换,称为向上类型转换。
因为 int:4字节,赋值或拷贝给 long long int:8字节,不会造成内存越界/溢出,数据精度不会丢失。赋值后 temp_l 的值为 0x12345678,这种情况的强制类型转换没有内存安全性的风险,可以放心使用。
int temp = 0x12345678
long long int temp_l = (long long int)temp;
向下强制类型转换
long long int:8字节,int:4字节,由 long long int 类型,转换到 int类型,类似于这种的基本变量类型转换,称为向下类型转换。
因为long long int:8字节:8字节,赋值或拷贝给 int:4字节,数值超出 int 型数值范围,造成内存溢出,后4字节的数据直接溢出,导致数据精度丢失。赋值后 temp的值为 0x12345678,这种情况的强制类型转换,数据精度丢失。
long long int temp_l = 0x1234567812345678
int temp = (int)temp_l;
伙伴们可以按照上述的示例代码,动手敲一遍,顺便复习一下GDB调试
创作不易,动动发财的小手点个关注再走呗