When you accessing block of memory (f.e. in real case using mmap) correct pointer for sem_t have to by multiple of 4. If it is not, then sem_init() still doesn't return -1 (error value), but sem_t isn't valid. Why it is working like this?
Below code that is showing behaviour of semaphores.
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <strings.h> //bzero
int main(int argc, const char *argv[]) {
//sizeof(sem_t) == 32 on 86_64, 16 on 86
void *adrr = malloc(sizeof(sem_t)*2);
bzero(adrr, sizeof(sem_t)*2);
sem_t *sem1 = adrr+1;
if(sem_init(sem1, 1, 0) == -1) printf("ERROR\n");
sem_wait(sem1);
printf("Not working\n");
bzero(adrr, sizeof(sem_t)*2);
sem_t *sem2 = adrr+2;
sem_init(sem2, 1, 0);
sem_wait(sem2);
printf("Not working\n");
bzero(adrr, sizeof(sem_t)*2);
sem_t *sem3 = adrr+3;
sem_init(sem3, 1, 0);
sem_wait(sem3);
printf("Not working\n");
bzero(adrr, sizeof(sem_t)*2);
sem_t *sem4 = adrr+4;
sem_init(sem4, 1, 0);
sem_wait(sem4);
printf("Working\n");
free(adrr);
return 0;
}