0

I know what every command does within my code, I just don't know the reasons they're there in the first place. This is insanely difficult to search answers for as my questions relate mostly to my own program. Apologies if it's still un-answerable, I will endeavor to improve my future questions :).

I need to write a program that can communicate across shared memory, taking turns to create and delete processes. I'm trying to understand the piece of code I was given, in particular the bit below. At the very bottom I've included the whole producer code in case it helps anyone answer my question.

THE QUESTION: Why is *randNum incremented past 101 when later, the condition for it to print the output IS it being equal to 101?

Does this hint at the Consumer having to change the value contained in the location *randNum in order for the condition to be met?

for(A = 0; A < size; A++)    // for loop to reset all priority values so that they are clear to be used in the next set
    {
        *randNum = 101;
        *randNum++;
    }

The if command later on:

if(*randNum == 101)
{
    *randNum = rand() % (100 - 1) + 1;
    *pidNum = getpid();

    printf("priority: %d Process ID: %d \n", *randNum, *pidNum);

    x = 1;
}

As promised, full program below for completion purposes (trying to make it easier on you and prevent questions; also to provide context)

#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <unistd.h>


void shm2sz(int size);

int main(int argc, char *argv[])


{
    int shmid, A, B, count, *shm, *randNum, *pidNum, pid, *memSig;
    
    key_t key;
    
    int size = atoi(argv[1]);
    
    int shmsz = (size * 2) + 1;  // declaring size of shared mem to be twice the size of user input, + 1 for owner ID
    
    int x = 0;
    
    int noToCreate = atoi(argv[2]);

    shm2sz(shmsz);
    key = 2060;        // Identifier key for SharedMem

    shmid = shmget(key, shmsz, IPC_CREAT | 0666);  //creating Sharedmem

    if(shmid < 0)   // variable if sharedmem is less than 0, print error.
    
            {
                    perror("shmget");    // eror mesage print
                    exit(1);
            }

    shm = shmat(shmid, NULL, 0);    //Attach to shared mem, if fails.. proceed with error message

    if(shm == (int *) -1)   // eror message
    
        {
                perror("shmat");
                exit(1);
        }

    
    randNum = shm;         // declare randNum equal to shm
    
    pidNum = shm + size;   // set pid to the first bit of the second part of the shared mem

    memSig = shm + shmsz;  // set memsig as final value in shared mem
    
    *memSig = 0;

    for(A = 0; A < size; A++)    // for loop to reset all priority values so that they are clear to be used in the next set
    {
        *randNum = 101;
        *randNum++;
    }

    count = 0;      // set count back to 0

    randNum = shm;              //check randNum equal to shm
    pidNum = shm + size;

    while(*memSig != 2)
    {
        while(*memSig == 1)   // set memsignature to sleep while..
        {
            sleep(1);
        }
    
        for(B = 0; B < noToCreate; B++)     
        {
            pid = fork();
    
            if(pid == -1)
            {
                perror("Error forking");
                exit(1);
            }
            else if(pid > 0)
            {
                wait(0);
            }
            else
            {
                srand(getpid());
    
                while(x == 0)
                {
                    if(*randNum == 101)
                    {
                        *randNum = rand() % (100 - 1) + 1;
                        *pidNum = getpid();

                        printf("priority: %d Process ID: %d \n", *randNum, *pidNum);

                        x = 1;
                    }
                    else
                    {
                        *randNum++;
                        *pidNum++;
                    }
                }
                exit(0);
            }
        } /* Closes main for loop */

        if(*memSig == 0)
        {
            *memSig = 1;
        }
    } /* Closes main while loop */
}

void shm2sz(int size)
{
    int shmid, *shm2;
    key_t key;
    
    key = 9876;

    shmid = shmget(key, 2, IPC_CREAT | 0666);

    if(shmid < 0)
    {
        perror("shmget2");
        exit(1);
    }

    shm2 = shmat(shmid, NULL, 0);
    
    if(shm2 == (int *) -1)
    {
        perror("shmat2");
        exit(1);
    }

    *shm2 = size;
}
VLAZ
  • 26,331
  • 9
  • 49
  • 67
viKK
  • 15
  • 1
  • 7

1 Answers1

1

The operator precedence for the postfix increment operator is higher than the pointer dereference operator. This means that *randNum++ actually increases the pointer randNum.

If you want to increment the value pointed to by randNum you have to use parentheses:

(*randNum)++;
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • 1
    and `(*pidNum)++;` as well :) –  Jul 29 '13 at 13:06
  • Ah, that's quite the subtle distinction :). Thanks! Does that mean that if it were (*randNum)++ the value being pointed to would be 102 after one cycle of the for loop? Conversely, does that mean that randNum++ after one cycle no longer points to 101, but to whatever value after 101 (not 102)? – viKK Jul 29 '13 at 13:19
  • @user2618840 Yes to both questions. – Some programmer dude Jul 29 '13 at 13:22
  • Okay, so the for loop sets 101 in the addresses from 0 to size? *randNum = 101 *randNum++ = 101 *randNum+2 = 101 etc – viKK Jul 29 '13 at 13:34
  • 1
    @user2618840 Yes, but no need to separate the assignment and increment: `*randNum++ = 101;` is enough. – Some programmer dude Jul 29 '13 at 13:37