野指针问题
最近在看之前的代码,对之前的bug有些新的认识,这里总结下,学疏才浅,跟大家分享下吧。
首先是用到了一个发送函数
static int send_fun(uint16_t length, uint8_t *data);
需要根据不同的条件判断发送的数据 data
以下实现是错误的
int judge_send_fun(void)
{
int ret;
uint8_t *data;
if(XXX)
{
*data = 0;
ret = send_fun(1, data);
}
else if(XXX)
{
*data = 1;
ret = send_fun(1, data);
}
return ret;
}
错误的原因是函数中定于的uint8_t *data 是一个野指针,在函数调用send_fun函数之前,会把judge_send_fun函数的局部变量和静态变量和跳转回来的程序位置以及send_fun的参数进行压栈(函数调用的实现可以看考《深入理解计算机系统》中的过程一节),这里压栈的只是一个存放data的地址,当data的地址做为参数传给send_fun时,只是传递了压栈是的指向data的指针,实际上由于data在声明时没有指向具体的内存空间(野指针),data的内容是不可靠的值,及send_fun函数根据传入的data的地址去寻找具体的数值时,得到的数值时一个随机的数字,导致程序运行错误。
正确的做法如下:
int judge_send_fun(void)
{
int ret;
uint8_t data;
if(XXX)
{
data = 0;
ret = send_fun(1, &data);
}
else if(XXX)
{
data = 1;
ret = send_fun(1, &data);
}
return ret;
}
这样在调用send_fun之前被压栈的是,data的数值和send_fun 参数&data,此时&data指向的地址,是被压栈的data的数值,不会出现data的数值被随机篡改的问题。