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("ERRORn"); sem_wait(sem1); printf("Not workingn"); bzero(adrr, sizeof(sem_t)*2); sem_t *sem2 = adrr+2; sem_init(sem2, 1, 0); sem_wait(sem2); printf("Not workingn"); bzero(adrr, sizeof(sem_t)*2); sem_t *sem3 = adrr+3; sem_init(sem3, 1, 0); sem_wait(sem3); printf("Not workingn"); bzero(adrr, sizeof(sem_t)*2); sem_t *sem4 = adrr+4; sem_init(sem4, 1, 0); sem_wait(sem4); printf("Workingn"); free(adrr); return 0; }
Advertisement
Answer
ALL1 types in C may have alignment requirements. These requirements are always implementation defined, and may be different on different architectures or even on different compilers on the same architecture (though that is rare).
Violating an implementation defined alignment requirement results in undefined behavior — anything may happen, though generally what happens is the program gets an error or crashes when accessing the misaligned object.
What you appear to have determined is that on your specific implementation, sem_t
has an alignment requirement of 4 — fairly common on 32-bit architectures. Other implementations may be different.
1You can argue that char
never has an alignment requirement, or that it’s alignment requirement is required to be 1