Strict aliasing, and alignment questions when partitioning memory

Viewed 111

My goal is to allocate a single chunk of memory and then partition it into smaller arrays of different types. I have a few questions about the code I've written here:

#include <iostream>
#include <cstdint>
#include <cstdlib>

int main() {
    constexpr std::size_t array_count   = 5;
    constexpr std::size_t elements_size = sizeof(std::uint32_t) + sizeof(std::uint16_t);

    void* const pv = std::calloc(array_count, elements_size);

    //Partition the memory. p32 array starts at pv, p16 array starts after the 20 byte buffer for the p32 array.
    std::uint32_t* const p32 = (std::uint32_t *) pv;
    std::uint16_t* const p16 = (std::uint16_t *)((char *) pv + sizeof(std::uint32_t) * array_count);

    //Initialize values.
    for(std::size_t i = 0; i < array_count; ++i) {
        p32[i] = i;
        p16[i] = i * 2;
    }

    //Read them back.
    for(std::size_t i = 0; i < array_count; ++i) {
        std::cout << p32[i] << std::endl;
        std::cout << p16[i] << std::endl;
        std::cout << std::endl;
    }

    std::free(pv);
}
  1. Does this code violate c++'s strict aliasing rules? I'm having trouble finding resources on aliasing when casting pointers from a malloc or calloc call. The p32 and p16 pointers should never overlap.
  2. If I reverse the positioning of the two arrays where p16 started at pv, and p32 had a 10 byte offset from pv this could cause a segfault because uint32_t is aligned to the 4 byte boundary pv + 10 could be on the 2 byte boundary, right?
  3. Is this program unsafe, or introduce any undefined behavior that I'm missing in general? I get the expected output on my local machine, but of course that doesn't mean my code is correct.
4 Answers
Related