keil定义的变量被更改_数组越界

keil定义的变量被更改_数组越界
✍概述
  在STM32程序调试CANFD(MCP2517驱动)的过程中,发现自己定义的数组莫名其妙的赋了值,就算自己赋了初值也会被更改。
  编译环境为Keil5,通过查看变量地址的方法来分析原因。

被改变的变量
  自己定义的数组为SensorValue[7],为其每个元素赋了初值0x0000。

uint16_t SensorValue[7]={0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000};//定义的数组

  在程序中没有对SensorValue[]数组进行任何赋值操作,但是在程序运行过程中Debug该数组的值如下图所示:

发现数组的第一个元素SensorValue[0]被更改。
在这里插入图片描述
通过Keil查看变量地址来分析原因
  在keil所在工程中用notepad++打开.map文件(里面可以看到所有变量的大小、地址等信息)。搜索出错的数组名SensorValue发现该数组的地址为0x24000208,大小为14个字节。
在这里插入图片描述
因为数组的第一个元素SensorValue[0]被更改,即该数组首地址处的数据被更改,所以我们查看该数组首地址0x24000208之前的一个地址的数据CAN3_spiReceiveBuffer是否越界操作到了SensorValue数组的数据。在程序中找到CAN3_spiReceiveBuffer定义:

#define SPI_DEFAULT_BUFFER_LENGTH 96
uint8_t CAN3_spiTransmitBuffer[SPI_DEFAULT_BUFFER_LENGTH];

该数组为96个字节,在.map文件中查看确实为96个字节。
在这里插入图片描述
之后在keil中按Ctrl+F搜索所有的CAN3_spiTransmitBuffer(调试莫名Bug不就得这样)发现(只看下面程序的两句)

int8_t CAN3_DRV_CANFDSPI_WriteByteArray(CANFDSPI_MODULE_ID index, uint16_t address,
        uint8_t *txd, uint16_t nBytes)
{
    uint16_t CAN3_i;
   uint16_t spiTransferSize = nBytes + 2;//只看这里!!!!!!
    int8_t spiTransferError = 0;

    // Compose command
    CAN3_spiTransmitBuffer[0] = (uint8_t) ((cINSTRUCTION_WRITE << 4) + ((address >> 8) & 0xF));
    CAN3_spiTransmitBuffer[1] = (uint8_t) (address & 0xFF);

    // Add data
    for (CAN3_i = 2; CAN3_i < spiTransferSize; CAN3_i++) {//只看这里!!!!!
        CAN3_spiTransmitBuffer[CAN3_i] = txd[CAN3_i - 2];
    }

    spiTransferError = CAN3_DRV_SPI_TransferData(index, CAN3_spiTransmitBuffer, CAN3_spiReceiveBuffer, spiTransferSize);

    return spiTransferError;
}

从程序第一处

uint16_t spiTransferSize = nBytes + 2;//只看这里!!!!!!

中发现spiTransferSize 的值为 spiTransferSize = 96(nBytes )+2,即spiTransferSize =98。观察Debug窗口确实为98:
在这里插入图片描述
再看程序第二处

for (CAN3_i = 2; CAN3_i < spiTransferSize; CAN3_i++) {//只看这里!!!!!
        CAN3_spiTransmitBuffer[CAN3_i] = txd[CAN3_i - 2];
    }

是在对大小为96字节的CAN3_spiTransmitBuffer数组进行96次的赋值,for循环从2开始到spiTransferSize,虽然执行了spiTransferSize-2次,即96次,但是却出现了CAN3_spiTransmitBuffer[96],CAN3_spiTransmitBuffer[97]的情况,而CAN3_spiTransmitBuffer数组大小为96字节,最大数组元素为CAN3_spiTransmitBuffer[95],所以数组越界了,越界了2个字节。在.map文件中查看CAN3_spiTransmitBuffer的首地址偏移96个字节就到了下一个变量SensorValue的地址
在这里插入图片描述
但是我们对CAN3_spiTransmitBuffer[96],CAN3_spiTransmitBuffer[97]也赋了值,这两个数据已经超越了CAN3_spiTransmitBuffer管辖范围了,所以就占用了SensorValue数组的前两个字节。所以就会出现我们没对SensorValue数组进行赋值操作内部元素的值却发生了变化:
在这里插入图片描述

总结: 数组越界会导致该数组占用内存后一位的数据发生变化,所以我们在平时操作数组的时候要避免这种情况的发生。

如有错误,欢迎指导!!!

猜你喜欢

转载自blog.csdn.net/qq_40147893/article/details/107338255