On most hardware architectures you can only change protection attributes on entire memory pages; you can’t mark a fragment of a page read-only.
The relevant APIs are:
mprotect()on Unix;VirtualProtect()on Windows.
You’ll need to ensure that the memory page doesn’t contain anything that you don’t want to make read-only. To do this, you’ll either have to overallocate with malloc(), or use a different allocation API, such as mmap(), posix_memalign() or VirtualAlloc().