0

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

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
super trainee
  • 117
  • 2
  • 11
  • Please [see why not to cast](http://stackoverflow.com/q/605845/2173917) the return value of `malloc()` and family in `C`. – Sourav Ghosh Jul 06 '15 at 09:33
  • you can also refer to [Pointer subtraction confusion](http://stackoverflow.com/questions/3238482/pointer-subtraction-confusion) – Eric Tsui Jul 06 '15 at 09:53
  • @Eric Tsui So when i do p2-tab it's addressp2 -addresstab = 4 bloc of int – super trainee Jul 06 '15 at 10:19
  • @supertrainee p2-tab = number of element that between p2 and tab – Eric Tsui Jul 06 '15 at 10:26
  • @Eric Tsui i found it strange, in my example: value of p2 = 47222160; value of tab = 47222144 and when i do... p2-tab = 4 (so 4x 4int). it is very confusing – super trainee Jul 06 '15 at 21:06
  • @supertrainee Because everything in pointer-land is about offsets, if p2-tab = 4 (this is `pointer substraction`)while p2 is with pointer type `int*`. it says the offset is 4. If you do (unsigned int)(p2)-(unsinged int)(tab), it would be 16(this is `int substracton`). – Eric Tsui Jul 06 '15 at 23:29

1 Answers1

2

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.

Community
  • 1
  • 1
axiac
  • 68,258
  • 9
  • 99
  • 134
  • @ axiac i found it strange, in my example: value of p2 = 47222160; value of tab = 47222144 and when i do... p2-tab = 4 (so 4x 4int). it is very confusing – super trainee Jul 06 '15 at 21:07
  • 1
    Using your values, `47222160-47222144=16` (bytes). `p2-tab`, on the other hand, is not a subtraction of bytes, it is [pointer arithmetic](https://en.wikipedia.org/wiki/Pointer_%28computer_programming%29#C_arrays). The unit on pointer arithmetic is not the byte but the size of the type pointed by `p2` and `tab` (and that type is `int`). You probably run your code on a 32bit processor and that means `sizeof(int) == 4` (bytes). `p2-tab = (47222160-47222144)/sizeof(int) = 16/4 = 4` (integers). – axiac Jul 06 '15 at 21:46