我正在尝试编写一个程序,它将通过串口从PIC16与XBee Pro S2B通信,并且我有一些奇怪的内存正在进行......
当涉及C中的指针时,我有点弱,所以我一直在使用GCC编写测试程序,以便在将其移至PIC单片机之前使其工作。 PIC最值得注意的是内存限制。所以为此,我想避免添加任何外部库,除非我绝对必须(并避免使用malloc / free)。
这是我的代码:
#include <stdio.h>
#define FALSE 0
#define TRUE 1
void printPacketArray(unsigned char *packetArray, int packetSize){
printf("OUTPUT PACKET: ");
for(int i = 0; i < packetSize; i++){
printf("%02X ", packetArray[i]);
}
printf("\n");
}
/**
* This function builds all of the frames to be wrapped into a packet
*/
int buildFrame(
unsigned char frameType,
unsigned char requestResponse,
unsigned char *destinationAddress64Bit,
unsigned char *destinationAddress16Bit,
unsigned char *rfPacketData,
int destinationAddress64BitSize,
int destinationAddress16BitSize,
int rfDataSize,
unsigned char **frameArray,
int **frameArraySize){
// printf("Entering buildFrame\n");
// FT RESP (Optional Dest Addr x64) + (Optional Dest Addr x16) Packet
int outputPacketSize = (1 + 1 + destinationAddress64BitSize + destinationAddress16BitSize + rfDataSize);
// printf("Packet Size: %d\n", outputPacketSize);
unsigned char outputPacketArray[outputPacketSize];
// Add the frame type
outputPacketArray[0] = frameType;
// printf("Frame type: %02X\n", frameType);
// Request response
outputPacketArray[1] = requestResponse;
// printf("Response: %02X\n", requestResponse);
int arrayCount = 2;
// Add the destination address (64 bit)
if(destinationAddress64Bit != 0x00){
for(int i = 0; i < 8; i++){
outputPacketArray[arrayCount] = destinationAddress64Bit[i];
// printf("outputPacketArray[%d] = %02X\n", arrayCount, destinationAddress64Bit[i]);
arrayCount++;
}
}
// Ad the destination address (16 bit)
if(destinationAddress16Bit != 0x00){
for(int i = 0; i < 2; i++){
outputPacketArray[arrayCount] = destinationAddress16Bit[i];
// printf("outputPacketArray[%d] = %02X\n", arrayCount, destinationAddress16Bit[i]);
arrayCount++;
}
}
// Add the packet data
for(int i = 0; i < rfDataSize; i++){
outputPacketArray[arrayCount] = rfPacketData[i];
// printf("outputPacketArray[%d] = %02X\n", arrayCount, rfPacketData[i]);
arrayCount++;
}
*frameArray = outputPacketArray;
// printf("*frameArray = %p\n", outputPacketArray);
*frameArraySize = &outputPacketSize;
// printf("*frameArraySize = %p\n", &outputPacketSize);
// printf("Packet: ");
// for(int i = 0; i < outputPacketSize; i++){
// printf("%02X ", outputPacketArray[i]);
// }
// printf("\n");
// printf("Exiting buildFrame\n");
return TRUE;
}
/**
* This function wraps the frame data into the packet.
*/
int buildPacket(
unsigned char *frameData,
int frameDataSize,
unsigned char **packetArrayPtr,
int **packetArraySizePtr){
// 7E MSB LSB Packet Checksum
int outputPacketSize = (1 + 1 + 1 + frameDataSize + 1);
int checksum = 0;
unsigned char outputPacketArray[outputPacketSize];
// Add the start delimiter
outputPacketArray[0] = 0x7E;
// Add the MSB (should always be 0x00)
outputPacketArray[1] = 0x00;
// Add the LSB (size of frameData)
outputPacketArray[2] = frameDataSize;
// Add the frame data
int arrayCount = 3;
for(int i = 0; i < frameDataSize; i++){
// printf("CNT: %d\n", arrayCount);
outputPacketArray[arrayCount] = frameData[i];
checksum += frameData[i];
arrayCount++;
}
// Add the checksum
outputPacketArray[arrayCount] = (0xFF - (checksum & 0xFF));
// printf("CNT: %d\n", arrayCount);
// printf("Packet: ");
// for(int i = 0; i < outputPacketSize; i++){
// printf("%02X ", outputPacketArray[i]);
// }
// printf("\n");
*packetArrayPtr = outputPacketArray;
*packetArraySizePtr = &outputPacketSize;
return TRUE;
}
int sendAPICommand(unsigned char* inputFrameData, int inputFrameDataLength){
unsigned char destinationAddress64Bit[] = {0x00, 0x13, 0xA2, 0x00, 0x40, 0x9C, 0x26, 0xE1};
unsigned char destinationAddress16Bit[] = {0xFF, 0xFE};
unsigned char *frameArrayPtr = 0x00;
int *frameArraySizePtr = 0x00;
// printf("COMPARE: 7E 00 13 10 01 00 13 A2 00 40 9C 26 E1 FF FE 00 00 01 02 03 04 05 4A\n");
// We need to add in the radius and options before the data
unsigned char frameData[(inputFrameDataLength + 2)];
frameData[0] = 0x00; // Radius
frameData[1] = 0x00; // Options
for(int i = 0; i < inputFrameDataLength; i++){
frameData[(i + 2)] = inputFrameData[i];
}
if(buildFrame(0x10, 0x01, destinationAddress64Bit, destinationAddress16Bit, frameData, 8, 2, (inputFrameDataLength + 2), &frameArrayPtr, &frameArraySizePtr) == TRUE){
printf("COMPARE: 10 01 00 13 A2 00 40 9C 26 E1 FF FE 00 00 01 02 03 04 05\n");
printPacketArray(frameArrayPtr, *frameArraySizePtr);
// The building of the frame was a success
if(buildPacket(frameArrayPtr, *frameArraySizePtr, &frameArrayPtr, &frameArraySizePtr) == TRUE){
printf("COMPARE: 7E 00 13 10 01 00 13 A2 00 40 9C 26 E1 FF FE 00 00 01 02 03 04 05 4A\n");
printPacketArray(frameArrayPtr, *frameArraySizePtr);
return TRUE;
}
}
return FALSE;
}
int main(){
unsigned char packetData[] = {0x01, 0x02, 0x03, 0x04, 0x05};
sendAPICommand(packetData, 5);
return 0;
}
当我运行它时,我似乎无法找出结果不一致的原因。使用Eclipse调试器,我收到以下错误:
frameData.15 Error: Multiple errors reported.\ Failed to execute MI command: -var-create - * frameData.15 Error message from debugger back end: mi_cmd_var_create: unable to create variable object\ Failed to execute MI command: -var-create - * frameData.15 Error message from debugger back end: mi_cmd_var_create: unable to create variable object\ Failed to execute MI command: -data-evaluate-expression frameData.15 Error message from debugger back end: No symbol "frameData" in current context.\ Failed to execute MI command: -var-create - * frameData.15 Error message from debugger back end: mi_cmd_var_create: unable to create variable object\ Unable to create variable object
在这行代码上:
if(buildFrame(0x10, 0x01, destinationAddress64Bit, destinationAddress16Bit, frameData, 8, 2, (inputFrameDataLength + 2), &frameArrayPtr, &frameArraySizePtr) == TRUE){
当我完全运行程序时(它默默地失败),这是我的文本输出:
COMPARE: 10 01 00 13 A2 00 40 9C 26 E1 FF FE 00 00 01 02 03 04 05
OUTPUT PACKET: 01 00 00 00 00 00 00 00 D8 8C 28 03 01 00 00 00 B0 8A 97 5C FF 7F 00 00 08 00 00 00 00 00 00 00 00 8A 97 5C 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 FF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10 00 00 00 30 00 00 00 90 8A 97 5C FF 7F 00 00 90 89 97 5C FF 7F 00 00 00 00 00 00 00 00 00 00
我怀疑问题是我有一个错误的指针(或指针)返回大小或指向字符数组的指针,但我不确定(或知道如何让程序失败的方式)我可以确定它)。
答案 0 :(得分:1)
在buildFrame
:
unsigned char outputPacketArray[outputPacketSize];
outputPacketArray
是一个局部变量。当你离开这个功能时,它的生命终结。但是,您将指向它的指针分配给函数的输出参数:
*frameArray = outputPacketArray;
(outputPacketSize
相同)
离开函数时,这些指针不再指向有效内存。您需要动态分配数组:
unsigned char* outputPacketArray = malloc(outputPacketSize);
然后将其释放。或者,您可以为函数提供适当大小的数组,但是您需要计算main
中已有的大小。
对于大小你根本不需要指向指针的指针,只需从函数返回它,或者使用一个简单的指针(而不是双指针)作为输出参数。