super trainee
super trainee

Reputation: 117

Pointers behaviour

This programm ask the user to fill a table and ask the value he want to delete then make the new table without the value

#include<stdio.h>
#include<stdlib.h>

main()
{
int *tab;
int *p1,*p2;
int nb,val,i;

printf("Number of values for the table ? ");
scanf("%d",&nb);

tab=(int*)malloc(nb*sizeof(int)); // on alloue le nombre de cases demandees au tableau

for (i=0;i<nb;i++)
    {
    printf("value n %d of the table? ",i);
    scanf("%d",&tab[i]);
    }

printf("\n value to delete of the table ? ");
scanf("%d",&val);

p1=tab; // on fait pointer p1 s ur la premiere case du tableau
p2=tab; // idem pour p2

// p1 va parcourir le tableau tout entier
// p2 n'avancera que si l'element du tableau en cours est different de val

while (p1<tab+nb) // tant qu'on n'est pas a la fin du tableau
    {
    if (*p1!=val) // si l'element en cours est different de val
        {
        *p2=*p1; // on recopie l'element dans la case pointee par p2
        p2++;   // on incremente p2 pour passer a la case suivante
        }
    p1++;
}

for (i=0;i<*p2-*tab;i++) // p2-tab= nombre de cases encore remplies
    {
    printf("value n %d of the table : %d\n",i,tab[i]);
    }

}

I don't understand why the last for loop can be write like this as well ?

for (i=0;i<p2-tab;i++)

it should not return the value of the address, only the address

Upvotes: 0

Views: 92

Answers (1)

axiac
axiac

Reputation: 72177

for (i=0;i<*p2-*tab;i++) exposes undefined behaviour and it is semantically wrong anyway.

The correct code is:

for (i=0;i<p2-tab;i++)
{
    printf("value n %d of the table : %d\n",i,tab[i]);
}

i is used as an index in tab (tab[i]), p2 points to the first element after the last element of the array after the elements equal with val were removed. p2-tab is the number of elements in the array after removal which is the correct number of iterations to do in order to print the remaining numbers.

Why is for (i=0;i<*p2-*tab;i++) wrong?

From the semantically point of view, *p2 and *tab are two elements in the array (ignore the case when *p2 is beyond the array boundaries, we'll talk about it two paragraphs below).

Consequently, *p2-*tab is some random number, it can be even negative. It doesn't make any sense to use it as the number of iterations over the array.

From the language point of view, if val is not present in the initial content of the array, after its "removal", p2 is equal to tab+nb. But tab points to a block of allocated memory that can hold at most nb values and that means tab+nb is outside this memory block.

This makes the code have undefined behaviour and that means anything could happen; some times it runs apparently well; most of the times it produces unexpected results; depending on the OS and compiler implementations, it can also generate an unhandled exception and be terminated by the OS.

Upvotes: 2

Related Questions