0

I try to display all values of tab but only 8 first elements are displayed no more

int tab[] = {0,2,5,3,9,0,8,9,2,0,4,3,0};
printf("taille %d: \n", sizeof(tab));

    for (int i=0; i<sizeof(tab); i++)
    {
        printf("indice : %d et valeur :%d \n", i, *(tab + i ));
    }
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
langme
  • 1,672
  • 2
  • 9
  • 18
  • 1
    what is sizeof(tab)? – user253751 Mar 02 '21 at 12:52
  • 2
    The `sizeof` operator returns the size in ***bytes***. If sizeof(int)` is `4` (which is the most common) then `sizeof(tab)` will be `52` bytes, so you'll loop over 52 elements in your 13-element array. Which will be way out of bounds. – Some programmer dude Mar 02 '21 at 12:52
  • 1
    On another note, why `*(tab + i )`? Why not `tab[i]`? – Some programmer dude Mar 02 '21 at 12:53
  • It will actually print 52 elements on most systems (causing undefined behavior). Post the actual code you tested. I'm guessing that in that code `tab` is actually a pointer. – interjay Mar 02 '21 at 12:53
  • `sizeof(tab)` -> `sizeof(tab) / sizeof(tab[0])` – alex01011 Mar 02 '21 at 12:55
  • 2
    "only 8 first elements" looks weird. This might be your actual problem: [C sizeof a passed array - Stack Overflow](https://stackoverflow.com/questions/5493281/c-sizeof-a-passed-array) – MikeCAT Mar 02 '21 at 12:56
  • Please show the real code. Something that can be compiled and reproduces the problem. According to your comment to a given answer, this is not showing the code you actually use. – Gerhardh Mar 02 '21 at 13:26
  • Your current code (after edits) should only print *one* element, since both `sizeof( tab )` and `sizeof( *tab )` will give the same result (since both a pointers), meaning that `size_tab` will be equal to `1`. – Some programmer dude Mar 02 '21 at 13:40
  • Furthermore, `*(tab + i)` is still exactly the same a `tab[i]` (it's defined in the C specification). And `tab[i]` is a pointer to an `int` so the `%d` format will be wrong. Not to mention that the function-argument `tab` doesn't match the argument you really pass to the function (in the `main` function the type of the expression `&tab` is `int (*)[13]`), very different from `int *[]` which is the same as `int **`). – Some programmer dude Mar 02 '21 at 13:43

2 Answers2

4

sizeof(tab) yields the size in bytes of all the array tab that contains 13 elements each of them having the size equal to sizeof( int ) (that is the same as sizeof( *tab )). That is

sizeof(tab) is equal to 13 * sizeof( int ) that in turn can be equal to 52 provided that sizeof( int ) is equal to 4.

But you need to output only 13 elements of the array.

So you should write for example

int tab[] = {0,2,5,3,9,0,8,9,2,0,4,3,0};
const size_t N = sizeof( tab ) / sizeof( *tab );

printf( "taille %zu: \n", N );

for ( size_t i = 0; i < N; i++ )
{
    printf( "indice : %zu et valeur :%d \n", i, *(tab + i ) );
}
putchar( '\n' );

Pay attention to that to output an object of the type size_t you need to use the conversion specifier zu.

Here is a demonstrative program where the array output is placed in a separate function.

#include <stdio.h>

FILE * output( const int tab[], size_t n, FILE *fp )
{
    fprintf( fp, "taille %zu: \n", n );

    for ( size_t i = 0; i < n; i++ )
    {
        fprintf( fp, "indice : %zu et valeur :%d \n", i, *(tab + i ) );
    }
    
    return fp;
}

int main(void) 
{
    int tab[] = {0,2,5,3,9,0,8,9,2,0,4,3,0};
    const size_t N = sizeof( tab ) / sizeof( *tab );

    fputc( '\n', output( tab, N, stdout ) );

    return 0;
}

The program output is

taille 13: 
indice : 0 et valeur :0 
indice : 1 et valeur :2 
indice : 2 et valeur :5 
indice : 3 et valeur :3 
indice : 4 et valeur :9 
indice : 5 et valeur :0 
indice : 6 et valeur :8 
indice : 7 et valeur :9 
indice : 8 et valeur :2 
indice : 9 et valeur :0 
indice : 10 et valeur :4 
indice : 11 et valeur :3 
indice : 12 et valeur :0 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

The line

printf("taille %d: \n", sizeof(tab));

invokes undefined behavior, allowing anything to happen, by passind data having wrong type to printf(). %d expects int, but sizeof returns size_t. The correct format specifier to print size_t in decimal is %zu.

Then, sizeof(tab) is the size of the array tab in bytes (number of char, strictly speaking). It is not the number of elements. To obtain the number of elements, you have to divide that by the size of one element sizeof(*tab).

int tab[] = {0,2,5,3,9,0,8,9,2,0,4,3,0};
printf("taille %zu: \n", sizeof(tab));

for (int i=0; i<sizeof(tab)/sizeof(*tab); i++)
{
    printf("indice : %d et valeur :%d \n", i, *(tab + i ));
}
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
  • with your code i have in result : indice 0 value 0 and indice 1 value 2 only printed – langme Mar 02 '21 at 13:02
  • @langme I have correct result: [https://wandbox.org/permlink/RlnD3RJGMwAsigOV](https://wandbox.org/permlink/RlnD3RJGMwAsigOV) – MikeCAT Mar 02 '21 at 13:04
  • works if i put all in main function but doesn't work if i make a display function... – langme Mar 02 '21 at 13:19
  • 1
    @langme in that case you failed to show us your code. Using an array that was passed as parameter is something completely different than what you showed us. In that case follow the link that was given my MikeCAT as comment half an hour ago. – Gerhardh Mar 02 '21 at 13:24
  • @langme Then my guess is that the "array" is really a pointer, and `sizeof(any_pointer)` will be the size of the pointer itself, not whatever it might point to. This fits with your claim that it only prints 8 elements, as the size of a pointer on a 64-bit system typically is 8 bytes. – Some programmer dude Mar 02 '21 at 13:25