前车之鉴,后事之师

1. 类型转换导致的内存溢出问题

C语言虽然同时支持有符号数据和无符号数据类型。但是最好不要随意用无符号数据类型。因为在隐士类型转换情况下,如果是有符号数据转换为无符号数据类型,程序会出现意想不到的bug。

下边列举一个有符号数据,隐士转换为无符号数据类型后,导致的内存错误。

直接撸代码:

#include<stdio.h>
float sum_elements(float a[], unsigned length)
{
	int i;
	float result = 0;
	for (i=0; i<=length -1; i++)
	{
		printf("when the length is zero, there will be memory issue\n");
		result  += a[i];
	}

	printf("the result is %f\n", result);

	return result;
}

int main()
{
	float array[5] = {1.0, 2.0, 3.0, 4.0, 5.0};
	sum_elements(array, 0);
}

问题分析
运行上边代码,因为length传递的值是0,length-1 就变成有符号值,而length定义的是无符号值,这里会发生一个隐士转换,然后length-1就变成的无符号数的最大值,所以for循环是一直满足条件的,这个时候数组a就会出现内存越界的情况。从而导致程序崩溃。

改进措施
将sum_elements的参数length的类型改为signed类型。或者,将小于等于改成<length, 不需要length-1;然后问题就迎刃而解。有木有很神奇!!!

案例2

C++案例

//this function is buggy
unsigned i = 3;
cout << i * -1 << endl;

问题分析
先说结果,4294967293.
因为i*(-1)的值隐士转换成了unsigned,所以就是3 * (0XFFFF FFFF),然后值溢出,除以2^32取模,结果就是4294967293.

2. 数组越界的问题

直接show代码
下边的代码有可能陷入死循环,为什么?

#include <stdio.h>
#include <stdint.h>

int main()
{
	uint16_t arr_p[5], i;

	for (uint16_t i = 1; i <= 5; ++i)
	{
		arr_p[i] = 0;
	}

	return 0;
}

解析
栈空间的生长方向是向上的(从高地址->低地址),数组arr_p[5]已经越界了,刚好有可能越界的指针指向了i的地址空间,这个时候i的值清零,所以for循环一直满足条件,将无限循环下去。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值