Rajat
Rajat

Reputation: 1

printf causes code crash

I am working on MODBUS creating library. Library is working fine for testing purpose I am using a Modbus based Power meter. I am facing a very strange problem. Trying to print value on console, by using printf. By fetching first value side by side I am printing it, on second fetch value is coming in array correctly but on using pritnf code get crashed. :( I have tried to debug the code also and came to know on using printf for a value second time code get crashed.

Here is part of code:

int wmain(void)
{
    FLOAT dataFloat[5] = {0};
    CHAR dataBuffer[200] = {0};
    // Initializing Structure declared in library header
    psModbusRTU pModbus =(psModbusRTU)malloc(sizeof(psModbusRTU)); 

    // Array pointer to store data
    BYTE *readData = (BYTE *) malloc(NUMBER_OF_READ_REGISTERS * sizeof(BYTE));
    memset(readData, 0, NUMBER_OF_READ_REGISTERS * sizeof(BYTE));   

    // Function to read the voltage
    if (!ModbusRTUReadRegister(pModbus, FC_READ_HOLDING_REGISTERS, VOLTAGE_REGISTER_ADDRESS, NUMBER_OF_READ_REGISTERS, readData))
    {
        printf("\nERROR Read register error %d", GetLastError());
        getchar();
        return 0;
    }
    dataFloat[0] = hexToFloatPointConversion(readData);
    printf("\nvoltage : %f", dataFloat[0]);  //(THIS IS FIRST PRINTF TILL HERE CODE IS FINE)

    /// Function reads the frequnecy
    if (!ModbusRTUReadRegister(pModbus, FC_READ_HOLDING_REGISTERS, FREQUENCY_REGISTER_ADDRESS, NUMBER_OF_READ_REGISTERS, readData))
    {
        printf("\nERROR Read register error %d", GetLastError());
        getchar();
        return 0;
    }
    dataFloat[1] = hexToFloatPointConversion(readData); // Saving frequency value in array
    printf("\nFrequency : %f", dataFloat[1]); // (THIS IS WHERE PROBLEM ARISES CODE CRASH WITH NO REASON)

hexToFloatPointConversion Function:

FLOAT hexToFloatPointConversion(BYTE *readData)
{
    DWORD dataHex = 0;
    DWORD exponent = 0;
    DWORD fraction = 0;
    DWORD signBit = 0;
    FLOAT dataFloat = 0;

    /// Saving BYTE array data into one DWORD
    dataHex = readData[0];
    dataHex = dataHex << 8;
    dataHex = dataHex + readData[1];
    dataHex = dataHex << 8;
    dataHex = dataHex + readData[2];
    dataHex = dataHex << 8;
    dataHex = dataHex + readData[3];    

    /// Getting sign bit, exponent and fraction
    signBit = dataHex >> 31;
    exponent = (dataHex >> 23 & 0xFF);
    fraction = dataHex & 0x7FFFFF;

    /// Calculation for converting data into float.
    dataFloat = (pow(2, (exponent - SINGLE_PRECISION_CONSTANT)) * ( 1 + (fraction * pow(2, -23))));

    return dataFloat;
}

psModbusRTU structure:

typedef struct sModbusRTU
{   
    HANDLE  hModbus; 
    BYTE    slaveNumber;
    BYTE    functionCode;           
    BOOL    fModbusInitialize;
    BOOL    fSlaveAddress;   
    BOOL    fModbusOpen;
    BOOL    fException; 
    WCHAR   portName[16];
    DWORD   exceptionData;
    DCB     dcb;
}sModbusRTU, *psModbusRTU;

Tried to debug also in run time and looked into dis-assembly break point but did not get exactly why it is happening. Here is the dis-assembly:

40050658  str         r3, [sp, #0x14] 
4005065C  str         r5, [sp, #8] 
40050660  str         r2, [sp] 
40050664  str         r4, [sp, #4] 
40050668  bl          40031078 
4005066C  __debugbreak_ce         //Break point
40050670  mvn         r3, #0x37, 24 
40050674  eor         r3, r3, #0xAB 
40050678  ldr         r2, [r3] 
4005067C  movw        r3, #0xF7F8 
40050680  movt        r3, #0xF101 

Please help me out, my project is stuck in middle just because of this small problem. Please respond back soon

Upvotes: 1

Views: 1090

Answers (2)

chux
chux

Reputation: 153447

Wrong size passed to malloc().

// was psModbusRTU pModbus =(psModbusRTU)malloc(sizeof(psModbusRTU));
// -----------------------------------------------v--------------
psModbusRTU pModbus = (psModbusRTU) malloc(sizeof(*psModbusRTU));  

Suggest alternate malloc() idiom. Use sizeof(*target).
Also, unless you compiler requires it (which it shouldn't), recommend dropping the cast

// example
psModbusRTU *pModbus = malloc(sizeof(*pModbus));

Upvotes: 1

David LaPorte
David LaPorte

Reputation: 231

The %f specifier is expecting to format a double (8 bytes) and not a float (4 bytes) (See this MSDN page for details. Try casting the values to double in your printf statements, e.g. printf("\nvoltage : %f", (double) dataFloat[0]);

Upvotes: 0

Related Questions