Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between while(tab[i+1] == 0) and while(tab[++i] == 0)

Tags:

c

I can't understand why if I use

    while (tab[i+1] == 0)
    {
        i+=1;
    }

My program hangs but if I use

 while (tab[++i] == 0);

It executes as it should. What am I missing?

Full code:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <limits.h>

#define SIZE 100

typedef struct
{
    unsigned int prime;
    unsigned int size;
    unsigned int *tab;
} shared_data;

void *sieve(void *);

sem_t mutex;

int main()
{
    pthread_t tid;
    unsigned int tab[SIZE];

    sem_init(&mutex, 0, 0);

    for (unsigned int i = 0; i < SIZE; i++)
    {
        tab[i] = i;
    }

    unsigned int i = 2; //index startowy
    shared_data shared = {i, SIZE, tab};
    while (i < SIZE)
    {

        shared.prime = tab[i];

        pthread_create(&tid, NULL, sieve, &shared);

        sem_wait(&mutex);

        while (tab[++i] == 0);
    }
    pthread_join(tid, NULL); // czekaj az ostatni watek zakonczy dzialanie

    sem_destroy(&mutex);

    printf("Liczby pierwsze:\n");

    for (unsigned int i = 0; i < SIZE; i++)
        if (tab[i]) //pomin 0 przy wyswietlaniu
            printf("%d | ", tab[i]);
    printf("\n");

    return 0;
}

void *sieve(void *arg_p)
{
    shared_data arg = *(shared_data *)arg_p;
    shared_data io = arg;
    int unlock_thread = 1;
    for (unsigned int i = io.prime + 1; i < io.size; i++)
    {
        if (io.tab[i] % io.prime == 0)
            io.tab[i] = 0;
        else if (unlock_thread)
        {
            sem_post(&mutex);
            unlock_thread = 0;
        }
    }
    if (unlock_thread)
        sem_post(&mutex);
    return NULL;
}
like image 870
Mateusz Avatar asked Jul 29 '26 10:07

Mateusz


1 Answers

    while (tab[i+1] == 0)
    {
        i+=1;
    }

Checks the next element of tab and doesn't change i when it is zero. This means i won't change to the value where tab[i] becomes zero.

In the other hand,

 while (tab[++i] == 0);

First go to the next element of tab and therefore i can be changed to make tab[i] zero.

To separate access to tab and update of i, you can do like this:

do {
    i+=1;
} while (tab[i] == 0);

Also note that you must not access (no read nor write) out-of-range elements of arrays. The array tab has only SIZE elements, so the available indices are only 0 to SIZE-1. This means you must not read tab[SIZE]. You should add range check to the loops like this:

while (++i < SIZE && tab[i] == 0);
do {
    i+=1;
} while (i < SIZE && tab[i] == 0);
like image 180
MikeCAT Avatar answered Aug 01 '26 02:08

MikeCAT



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!