确定C中字符数组的大小

时间:2014-01-19 19:31:57

标签: c pointers arrays

我正在尝试编写一个程序,它将通过串口从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 

我怀疑问题是我有一个错误的指针(或指针)返回大小或指向字符数组的指针,但我不确定(或知道如何让程序失败的方式)我可以确定它)。

1 个答案:

答案 0 :(得分:1)

buildFrame

unsigned char outputPacketArray[outputPacketSize];

outputPacketArray是一个局部变量。当你离开这个功能时,它的生命终结。但是,您将指向它的指针分配给函数的输出参数:

*frameArray = outputPacketArray;

outputPacketSize相同)

离开函数时,这些指针不再指向有效内存。您需要动态分配数组:

unsigned char* outputPacketArray = malloc(outputPacketSize);

然后将其释放。或者,您可以为函数提供适当大小的数组,但是您需要计算main中已有的大小。

对于大小你根本不需要指向指针的指针,只需从函数返回它,或者使用一个简单的指针(而不是双指针)作为输出参数。