尝试更新数组元素时出错

时间:2015-06-12 22:16:32

标签: c arrays pointers struct typedef

我正在开发一个没有调试功能的嵌入式平台。所以很难说出错误来源是什么。

我在头文件中定义了:

typedef struct cm_packet {
  CM_Header Header; //header of packet 3 bytes
  uint8_t *Data; //packet data 64 bytes
  CM_Footer Footer; //footer of  packet 3 bytes
} CM_Packet;

typedef struct cm_inittypedef{
  uint8_t               DeviceId;
  CM_Packet             Packet;        
} CM_InitTypeDef;

extern CM_InitTypeDef cmHandler;
void CM_Init(CM_InitTypeDef *handler);    
CM_AppendResult CM_AppendData(CM_InitTypeDef *handler, uint8_t identifier
                              , uint8_t *data, uint8_t length);

在实施的某个地方,我有:

uint8_t bufferIndex = 0;

void CM_Init(CM_InitTypeDef *cm_initer) { //init a handler
  cmHandler.DeviceId = cm_initer->DeviceId;  

  CM_Packet cmPacket;  
  cmPacket.Header.DeviceId = cm_initer->DeviceId;
  cmPacket.Header.PacketStart = CM_START;
  cmPacket.Footer.PacketEnd = CM_END;
  //initialize data array
  uint8_t emptyBuffer[CM_MAX_DATA_SIZE] = {0x00}; 
  cmPacket.Data = emptyBuffer;

  cm_initer->Packet = cmPacket;
}

CM_AppendResult CM_AppendData(CM_InitTypeDef *handler, uint8_t identifier
                              , uint8_t *data, uint8_t length){    
    //some check to see if new data does not make Data overflow             

    uint8_t i;

    /*** ERROR HAPPENS HERE!!!! ***/
    handler->Packet.Data[bufferIndex++] = identifier;

    //now add the data itself
    for(i = 0; i < length; i++) {
     handler->Packet.Data[bufferIndex++] = data[i];
    }

    //reset indexer
    if(bufferIndex > 64) {
       PacketReady(); //mark packet as ready
       bufferIndex = 0 
     };

    //return result
}

我们的想法是从有权访问Packet.Data的其他一些源代码更新handler。例如,其他一些来源可以调用Append函数来更改Packet.Data。但正如您在代码中看到的那样,我已经评论了导致微控制器进入硬故障模式的地方。我不确定这里发生了什么。我所知道的只是微线进入硬故障模式,永远不会恢复!

这可能是竞争条件,但在我想知道的任何事情之前,我已经写了正确的c!代码,然后我试图排除其他问题。

2 个答案:

答案 0 :(得分:3)

在函数cmPacket.Data中,您将uint8_t emptyBuffer[CM_MAX_DATA_SIZE] = {0x00}; cmPacket.Data = emptyBuffer; 设置为指向本地数组:

<?php

在函数范围之外访问此内存地址会产生未定义的行为。

答案 1 :(得分:1)

正如提到的@barak manos,提供给Data的缓冲区已分配到堆栈中。

当你到达CM_AppendData时,你正在编写不再专用于缓冲区的内存。

您可能希望使用malloc,以便在堆上而不是在堆栈上分配缓冲区。只记得打电话给free,这样你就不会泄漏记忆。

如果您无法使用动态分配,则可以为所有Data用途专用一些临时存储器。它只需要是静态的。

希望有所帮助:)