Memory alignment in heap_1.c file

Im a new to FreeRTOS and was going through the source code. I found the following line of code in the heap_1.c file line no. 98:

/* Ensure the heap starts on a correctly aligned boundary. */
pucAlignedHeap = ( uint8_t * ) ( ( ( portPOINTER_SIZE_TYPE ) & ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) );

I understand that pucAlignedHeap is getting assigned an aligned memory address from the beginning of the ucHeap array, but I’m confused why the statement uses ucHeap[ portBYTE_ALIGNMENT ] instead of ucHeap[ portBYTE_ALIGNMENT - 1 ].

For example if portBYTE_ALIGNMENT is 8 and portBYTE_ALIGNMENT_MASK is 7 and suppose ucHeap[ portBYTE_ALIGNMENT ] has an address 0x*******F, the aligned address variable, pucAlignedHeap will be getting assigned 0x*******8 which is basically the address of index 1 of the ucHeap array. That means 0th index of the array is not used even in the worst case. I believe there is something off with the way I’m visualising this. Please let me know what I’m missing.

Thanks

Is this related: https://forums.freertos.org/t/freertos-wasted-stack-space/13352

I think you are right. If we only consider last 4-bits of the address, does the following
correctly depict what you are trying to point:

ucHeap:

    0000     0001     0010      0011     0100     0101     0110      0111    1000
+---------+--------+--------+---------+--------+--------+--------+---------+---------+
|         |        |        |         |        |        |        |         |         |
|         |        |        |         |        |        |        |         |         |
|         |        |        |         |        |        |        |         |         |
|         |        |        |         |        |        |        |         |         |
+---------+--------+--------+---------+--------+--------+--------+---------+---------+ 

+--------+----------------------------------+---------------------------------------------------------------------------+
| ucHeap |  & ucHeap[ portBYTE_ALIGNMENT ]  | ( ( & ucHeap[ portBYTE_ALIGNMENT ] ) & ( ~( portBYTE_ALIGNMENT_MASK ) ) ) |
+--------+----------------------------------+---------------------------------------------------------------------------+
|   0000 |                             1000 |                                                                      1000 |
|   0001 |                             1001 |                                                                      1000 |
|   0010 |                             1010 |                                                                      1000 |
|   0011 |                             1011 |                                                                      1000 |
|   0100 |                             1100 |                                                                      1000 |
|   0101 |                             1101 |                                                                      1000 |
|   0110 |                             1110 |                                                                      1000 |
|   0111 |                             1111 |                                                                      1000 |
+--------+----------------------------------+---------------------------------------------------------------------------+


+--------+--------------------------------------+-------------------------------------------------------------------------------+
| ucHeap |  & ucHeap[ portBYTE_ALIGNMENT - 1 ]  | ( ( & ucHeap[ portBYTE_ALIGNMENT - 1 ] ) & ( ~( portBYTE_ALIGNMENT_MASK ) ) ) |
+--------+--------------------------------------+-------------------------------------------------------------------------------+
|   0000 |                                 0111 |                                                                          0000 |
|   0001 |                                 1000 |                                                                          1000 |
|   0010 |                                 1001 |                                                                          1000 |
|   0011 |                                 1010 |                                                                          1000 |
|   0100 |                                 1011 |                                                                          1000 |
|   0101 |                                 1100 |                                                                          1000 |
|   0110 |                                 1101 |                                                                          1000 |
|   0111 |                                 1110 |                                                                          1000 |
+--------+--------------------------------------+-------------------------------------------------------------------------------+

Thanks.

1 Like

This is not correct. The expression & ucHeap[ portBYTE_ALIGNMENT ] necessarily means ucHeap + portBYTE_ALIGNMENT. So if ucHeap is 0001, ucHeap + portBYTE_ALIGNMENT will be 1001. This, however, still wastes 8 bytes of memory in the case when ucHeap is 8 byte aligned.

1 Like

Yes you are correct. Initially I thought the first column of the tables in your initial reply was address of the each index of the same ucHeap array. Just now I realized that those values refer to the starting location of ucHeap array at different cases.

Thanks.