Search code examples
cpointersposixsemaphore

Dereferencing ‘void *’ pointer


I'm attempting to create a C program where the counter is incremented by alternating between the parent and child using the POSIX semaphore functions. So far I'm having trouble using it considering this is the first time I am using semaphore functions so if there is anything wrong with my program some pointers would be great as well.

So far my current issue is using the dereferencing void * pointer and I'm unsure how to go on since the mmap is a void pointer according to the Linux programmer's manual.

gcc -ansi -I -Wl -Wall -DLINUX -D_GNU_SOURCE    devzeroMyEdit.c  -L /lib -pthread -lrt -o devzeroMyEdit
devzeroMyEdit.c: In function ‘main’:
devzeroMyEdit.c:37:16: warning: dereferencing ‘void *’ pointer
  sem_init(&shmp->parent, 1, 0);
                ^~
devzeroMyEdit.c:37:16: error: request for member ‘parent’ in something not a structure or union
devzeroMyEdit.c:38:16: warning: dereferencing ‘void *’ pointer
  sem_init(&shmp->child, 1, 1);        /* Child first */
                ^~
devzeroMyEdit.c:38:16: error: request for member ‘child’ in something not a structure or union
devzeroMyEdit.c:40:13: warning: implicit declaration of function ‘fork’ [-Wimplicit-function-declaration]
  if ((pid = fork()) < 0) {
             ^~~~
devzeroMyEdit.c:45:18: warning: dereferencing ‘void *’ pointer
    sem_wait(&shmp->child);
                  ^~
devzeroMyEdit.c:45:18: error: request for member ‘child’ in something not a structure or union
devzeroMyEdit.c:50:18: warning: dereferencing ‘void *’ pointer
    sem_post(&shmp->parent);
                  ^~
devzeroMyEdit.c:50:18: error: request for member ‘parent’ in something not a structure or union
devzeroMyEdit.c:56:18: warning: dereferencing ‘void *’ pointer
    sem_wait(&shmp->parent);
                  ^~
devzeroMyEdit.c:56:18: error: request for member ‘parent’ in something not a structure or union
devzeroMyEdit.c:61:18: warning: dereferencing ‘void *’ pointer
    sem_post(&shmp->child);
                  ^~
devzeroMyEdit.c:61:18: error: request for member ‘child’ in something not a structure or union
<builtin>: recipe for target 'devzeroMyEdit' failed
make: *** [devzeroMyEdit] Error 1

My program:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <semaphore.h>

#define NLOOPS  1000
#define SIZE    sizeof(long)    /* size of shared memory area */

struct shmbuf{
    sem_t child;
    sem_t parent;
};

static int update(long *ptr)
{
    return((*ptr)++);       /* return value before increment */
}

int main(void)
{
    int     fd, i, counter;
    pid_t   pid;
    void    *shmp;

    if ((fd = shm_open("/dev/zero", O_RDWR, ALLPERMS)) < 0)
        perror("open error");

    if ((shmp = mmap(0, sizeof(struct shmbuf), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED)
        perror("mmap error");

    sem_init(&shmp->parent, 1, 0);
    sem_init(&shmp->child, 1, 1);        /* Child first */

    if ((pid = fork()) < 0) {
        perror("fork error");
    } else if (pid > 0) {                /* Parent */
        for (i = 0; i < NLOOPS; i += 2) {

            sem_wait(&shmp->child);

            if ((counter = update((long *)shmp)) != i)
                printf("parent: expected %d, got %d", i, counter);

            sem_post(&shmp->parent);
        }
    } else {                             /* Child */
        for (i = 1; i < NLOOPS + 1; i += 2) {

            sem_wait(&shmp->parent);

            if ((counter = update((long *)shmp)) != i)
                printf("child: expected %d, got %d", i, counter);

            sem_post(&shmp->child);
        }
    }

    return(0);
}


Solution

  • The type of shmp should obviously be struct shmbuf* and not void*. Dereferencing a void pointer doesn't make sense.

    shmp = mmap(0, ...) is legal, even if the type of shmp is not void*, because void pointers are safely promoted to any other pointer type.

    So just change void *shmp to struct shmbuf *shmp.

    Bonus: you also forgot #include <unistd.h>.