项目场景:
最近在做一个控制器项目,在控制器开发过程中遇到一个动态查表的问题,需要采集传感器的值,通过判断传感器值所在区间来获取相关的阈值,这样就可以为后续代码提供动态阈值。
问题描述:
这里遇到的问题是内存溢出,每次读取阈值的时候都提示内存溢出:
Segmentation fault
原因分析:
看到这个问题,我大概猜出来应该是指针搞错了,因为我函数的参数本来就是指针,我本意是改变指针的指向,然而实际上,这种写法不能改变指针的指向,只能修改指针指向的内存所存放的数据,我的错误代码如下:
INT32 get_current_level(UINT16 o2_data, UINT16* level)
{
int i, j;
if(o2_data <= o2h2_sheet[0][0]){
level = &o2h2_sheet[0][0];
return 4;
} else if(o2_data > o2h2_sheet[0][0] && o2_data <= o2h2_sheet[1][0]) {
level = &o2h2_sheet[1][0];
return 4;
} else if(o2_data > o2h2_sheet[1][0] && o2_data <= o2h2_sheet[2][0]) {
level = &o2h2_sheet[2][0];
return 4;
} else if(o2_data > o2h2_sheet[2][0] && o2_data <= o2h2_sheet[3][0]) {
level = &o2h2_sheet[3][0];
return 4;
} else if(o2_data > o2h2_sheet[3][0] && o2_data <= o2h2_sheet[4][0]) {
level = &o2h2_sheet[4][0];
return 4;
} else if(o2_data > o2h2_sheet[4][0]) {
level = &o2h2_sheet[4][0];
return 4;
}
return -1;
}
上面的函数就是用来查表的。事先定义一个二维数组,第一列用来和实际值比较,在范围内就取一个固定值,阈值就是第二列到第四列,这样就可以实现查表和阈值的动态变化。下面是我的数组定义:
static UINT16 level_sheet[5][4] = { {700,50,120,24},
{900,45,110,22},
{1100,40,100,20},
{1300,35,90,18},
{1500,30,80,16} };
解决方案:
这里找了一下相关的应用,应该是给函数传入一个指向指针的指针,下面是我传入的函数参数的定义:
static UINT16* make_level = NULL;
static UINT16* fc_level = NULL;
如果想修改make_level的指向,也就是指针本身的值,那么我应该给函数传入make_level这个指针存放的地址,然后修改这个地址内存放的数据,这样就改变了它的指向。
综上所述,正确的用法应该是这样的:
INT32 get_current_level(UINT16 o2_data, UINT16** level)
{
int i, j;
if(o2_data <= o2h2_sheet[0][0]){
*level = &o2h2_sheet[0][0];
return 4;
} else if(o2_data > o2h2_sheet[0][0] && o2_data <= o2h2_sheet[1][0]) {
*level = &o2h2_sheet[1][0];
return 4;
} else if(o2_data > o2h2_sheet[1][0] && o2_data <= o2h2_sheet[2][0]) {
*level = &o2h2_sheet[2][0];
return 4;
} else if(o2_data > o2h2_sheet[2][0] && o2_data <= o2h2_sheet[3][0]) {
*level = &o2h2_sheet[3][0];
return 4;
} else if(o2_data > o2h2_sheet[3][0] && o2_data <= o2h2_sheet[4][0]) {
*level = &o2h2_sheet[4][0];
return 4;
} else if(o2_data > o2h2_sheet[4][0]) {
*level = &o2h2_sheet[4][0];
return 4;
}
return -1;
}