提问人:Viermusketiere 提问时间:3/9/2023 最后编辑:DharmanViermusketiere 更新时间:3/9/2023 访问量:119
将指向对象的指针数组作为构造函数参数传递
Pass array of pointers to objects as constructor parameter
问:
我需要传递一个指向数组的指针,其中包含指向对象列表的指针作为新生成对象的构造函数参数。如果我设法让它在 ESP32 上编译和运行,似乎存在越界内存访问。
不要担心中断的措辞;系统正在读取外部MCP23017 GPIO扩展器的寄存器,该扩展器仅在内部处理中断。该例程旨在定期检查MCP23017s引脚之一是否发生中断,以及中断发生在哪个引脚上。然后,应选择与引脚对应的对象,并调用该对象的函数。action()
下面是编译的代码:
class StateManager {
private:
MCP *mcp1;
StateSensor * arrSensor;
public:
StateManager(MCP * pMcp1, StateSensor * pArrSensor);
void checkInterrupt();
};
//Constructor
StateManager::StateManager(MCP * pMcp1, MCP * pMcp2, StateSensor * pArrSensor) {
mcp1 = pMcp1;
mcp2 = pMcp2;
arrSensor = pArrSensor;
}
//Function in which the faulty access happens
void StateManager::checkInterrupt() {
uint8_t pinLI1 = mcp1->getLastInterruptPin();
ESP_LOGI(TAG, "pinLI1: %d", pinLI1);
if ( pinLI1 != 255 ) {
ESP_LOGI(TAG, "If clause reached");
for( uint8_t i = 0; i < 16; i++ ) {
ESP_LOGI(TAG, "for: %d, getPin(): %d", i, arrSensor[i].getPin());
if( arrSensor[i].getPin() == pinLI1 ) {
ESP_LOGI(TAG, "Hit: %d", i);
arrSensor[i].action();
break;
}
}
}
}
StateSensor sens01(1, &mcp02, 7);
StateSensor sens02(2, &mcp02, 6);
StateSensor sens03(3, &mcp02, 5);
StateSensor sens04(4, &mcp02, 4);
StateSensor * arrSens[32] = { &sens01, &sens02, &sens03, &sens04 }
StateManager sm1(&mcp02, &mcp03, *arrSens);
void setup() {
//...
}
void loop() {
sm1.checkInterrupt();
}
以下是 (1) 触发数组的第一个元素和 (2) 触发数组的第二个元素的日志输出,这会导致随机返回值。的预期值为 0 到 15。255 在未发生中断时返回。getPin()
mcp1->getLastInterruptPin()
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 255
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 255
(1)
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 7
[stateSensor.cpp:57] checkInterrupt(): [StateSensor] If clause reached
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 0, getPin(): 7
[stateSensor.cpp:61] checkInterrupt(): [StateSensor] Hit: 0
[stateSensor.cpp:35] action(): [StateSensor] 1 action!
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 255
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 255
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 255
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 255
(2)
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 6
[stateSensor.cpp:57] checkInterrupt(): [StateSensor] If clause reached
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 0, getPin(): 7
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 1, getPin(): 0
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 2, getPin(): 4
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 3, getPin(): 0
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 4, getPin(): 10
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 5, getPin(): 0
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 6, getPin(): 8
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 7, getPin(): 28
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 8, getPin(): 223
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 9, getPin(): 211
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 10, getPin(): 1
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 11, getPin(): 131
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 12, getPin(): 251
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 13, getPin(): 122
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 14, getPin(): 32
[stateSensor.cpp:59] checkInterrupt(): [StateSensor] for: 15, getPin(): 112
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 255
[stateSensor.cpp:55] checkInterrupt(): [StateSensor] pinLI1: 255
当触发数组的第一个或最后一个元素时,将从数组中读取指向对象的右指针。对于介于两者之间的所有元素,该操作将返回一个介于 0 和 255 之间的随机数。arrSensor[i].getPin()
如何有效地处理包含元素的数组的切换,同时解决越界内存访问的问题?还是我忽略了我方法中的一个根本错误?
答:
StateSensor * arrSensor;
是指向单个对象的指针,或者它是对象数组(不是指针 - 如 )。StateSensor
StateSensor
StateSensor * my_array = new StateSensor[10]
但是,看起来您想要一个指针数组,您可以将其声明为 并将构造函数的签名更改为 .(我猜你没有使用,因为这是一个微处理器)。StateSensor
StateSensor **
StateManager(MCP * pMcp1, StateSensor ** pArrSensor);
std::vector
此外,传递给构造函数,而不是整个数组。要传递数组,请使用 .StateManager sm1(&mcp02, &mcp03, *arrSens);
arrSens[0]
StateManager sm1(&mcp02, &mcp03, arrSens);
然后,您需要更改函数以处理指针数组,用于取消引用它们。checkInterrupt
->
for (uint8_t i = 0; i < 16; i++) {
ESP_LOGI(TAG, "for: %d, getPin(): %d", i, arrSensor[i]->getPin());
if (arrSensor[i]->getPin() == pinLI1) {
ESP_LOGI(TAG, "Hit: %d", i);
arrSensor[i]->action();
break;
}
}
这就引出了最后一点:循环最多可以迭代 16 次,但数组中只有 4 个指针。如果保证及时命中,则不是问题,但如果没有,则需要一种方法来确保不会读取数组的末尾或取消引用 .break
nullptr
评论
下一个:如何处理嵌入式系统的版本控制
评论