指向函数指针的 C 数组在超过一定长度时破坏程序

问题描述

嗨,我正在尝试从微控制器接收到的字符串中调用函数。为此,微控制器 find 接收并将其与外设名称列表中的名称进行比较。它使用索引来获取指向该外围设备可用的函数名称列表的指针,然后将函数名称与该列表进行比较以获取函数索引。然后使用这两个索引来调用函数

系统对 2 个外设工作正常,但添加第三个会导致程序停止运行,有时它会发出警告堆栈指针超出范围,有时它会在程序暂停时不显示任何位置。将第三个外设添加到peripheral_fnct_pntr_pntr 列表会导致这种情况发生,它可以在 2 个外设的所有组合中正常运行,注释该行也能正常工作。

我为函数指针创建了自定义类型,如下所示:

typedef void (*fp)(int); //Declares a type of a void function that accepts an int
typedef char (*p)[6][20]; //pointer to array 

函数和指针列表的创建如下所示:

    char peripheral_names[6][20] = {"rgb","button"};  //[no of strs][size of str]
    char rgb_fnct_names[6][20] = {"rgb_brightness","red_brightness","green_brightness","blue_brightness","rgb_onTime","rgb_breath"};
    char led1_fnct_names[6][20] = {"led1_brightness","led1_onTime","led1_breath"};
    char led2_fnct_names[6][20] = {"led2_brightness","led2_onTime","led2_breath"};

        //store pointers linking name to functiion index to function
    //rgb led functions pointers
    fp rgb_fnct_pntrs[] = {&rgb_brightness,&red_brightness,&green_brightness,&blue_brightness,&rgb_on_time,&rgb_breath};

    
    //led function pointers
    fp led1_fnct_pntrs[] = {&led1_brightness,&led1_on_time};
    fp led2_fnct_pntrs[] = {&led2_brightness,&led2_on_time};
    
    //store list of ponters to peripheral function pointer lists
    fp *perph_fnct_pntr_pntr[]  = {rgb_fnct_pntrs,led1_fnct_pntrs,led2_fnct_pntrs};


    
   //store pointers linking peripheral name index to list of function names
   p name_to_fnct_lst[3]= {&rgb_fnct_names,&led1_fnct_names,&led2_fnct_names};

我不确定是什么导致了这个问题,所以任何帮助将不胜感激。

解决方法

我猜它的工作方式是,你从一个字符串开始,通过遍历 name_to_fnct_lst[] 找到匹配的字符串,然后搜索它指向的数组 (rgb_fnct_names,{{1 }},led1_fnct_names)。当匹配时,您有两个索引(函数列表索引和列表中的名称)。

您使用第一个索引在 led2_fnct_names 中查找函数指针列表,然后使用第二个索引在 perph_fnct_pntr_pntrrgb_fnct_pntrsled1_fnct_pntrs 中查找索引。

这在 rgb 情况下有效,因为 led2_fnct_pntrsrgb_fnct_names 都有 6 个条目,但不适用于 led1/2,因为 rgb_fnct_pntrsled1_fnct_names 有 3 个条目,但是led2_fnct_namesled1_fnct_pntrs 有 2 个条目。我是否正确跟随?

如果是这样,看起来解决方案是将缺少的函数指针添加到 led2_fnct_pntrsled1_fnct_pntrs。或者它可能会简化将数组组合成 led2_fnct_pntrschar[3][6][20] 数组的事情(第一种情况没有缺点,无论如何您都在分配未使用的字符,第二种情况会丢失一些未使用的指针地址您可以从较小的代码中获益)。

另一种结构方式是:

fp[3][6]

这确保每个名称都有一个匹配的指针(并且不会浪费太多内存)。