Skip to content
Advertisement

Why sem_t pointer have to start at multiple of 4 offset?

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

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement