Search code examples
cpointersdynamic-memory-allocation

How can I make the second code works? (C code, sprintf and pointers)


I am using stm32f429 UART to send commands into a module. I prefer the second function code but I don't know how can I make it work. First function code, which works completely.

void v_cmd(unsigned short cmd)
{
    uint8_t cmd_packet[8];
    sprintf((char *)cmd_packet, "%02hu", cmd);
    HAL_UART_Transmit(&huart1, cmd_packet, 2, 100);
}

The Seconde function code, which doesn't work as the first code as I expected.

void v_cmd(unsigned short cmd)
{
    uint8_t *cmd_packet;
    sprintf((char *)cmd_packet, "%02hu", cmd);
    HAL_UART_Transmit(&huart1, cmd_packet, 2, 100);
}

Solution

  • It works it the first piece code because you are allocating memory for with

    uint8_t cmd_packet[8];
    

    As you must be aware of, this is allocating 8 bytes of memory.

    In the second piece of code you have shared, uint8_t *cmd_packet; is a pointer. But, you haven't allocated any memory where this point will point to. The code in its present state isn't functional because the pointer cmd_packet isn't initialized.

    The next statement,

    sprintf((char *)cmd_packet, "%02hu", cmd); 
    

    tries to populate the memory pointed by cmd_packet with data cmd. However, like I explained earlier, it isn't pointing to a valid address location where you can put this data. This ends up in a segmentation fault.

    Use malloc to allocate memory. You can refer the manual page for malloc.

    uint8_t *p_cmd_packet = malloc(8);
    

    The very next thing your code should do is to check if call to malloc has successfully allocated memory or not and some error handling if memory is not allocated.

    if(NULL == p_cmd_packet)
    {
        //! handle memory allocation error here
    }
    

    You also need to free this memory once you are done using it.

    free(p_cmd_packet);
    

    I see that the code you are developing is for an embedded microcontroller stm32f429. You also need to check in your startup assembly file for how much of heap is reserved/configured for application usage. Accordingly, you can handle memory allocations.

    I see another potential problem here:

    HAL_UART_Transmit(&huart1, cmd_packet, 2, 100);
    

    Ideally, if I were you, and used sprintf() to populate the data, I would have read the return value of sprintf() function and would use that value to pass as number of bytes to be transmitted. As of now, I can't comment more on this unless I know the exact parameters passed to HAL_UART_Transmit().