0

I've got an array which hold pointers to other arrays. I want to print all the values but i can't get the sizeof of the specific array. What am I doing wrong?

int main(void){
    int i, j;
    float T1[4]={1.1, 1.2, 1.3, 1.4};
    float T2[6]={2.1, 2.2, 2.3, 2.4, 2.5, 2.6};
    float T3[3]={3.1, 3.2, 3.3};
    float T4[2]={4.1, 4.2};
    float T5[4]={5.1, 5.2, 5.3, 5.4};

    float *TAB[5]={T1, T2, T3, T4, T5};
    for(i=0; i<5; i++){
        for(j=0; j<sizeof(TAB[i])/(sizeof (int)); j++){
            printf("%f ", *(TAB[i]+j));
        }
    }
    printf("\n");
}
ilim
  • 4,477
  • 7
  • 27
  • 46
shurrok
  • 795
  • 2
  • 13
  • 43

3 Answers3

7

You can't. Once an array has decayed to a pointer you no longer have the information about the size of the array. You need to keep track of it some other way.

In your case with the code shown, you could have a second array TAB_SIZES which contains the sizes of the arrays pointed to in TAB.


Also remember that for any array or pointer p and index i the expression p[i] is equal to *(p + i). That means you don't have to do *(TAB[i]+j). Instead do TAB[i][j], which feels more "natural" to most people.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • The first two sentences told me everything. I can see that dynamic part of this language works much different to my picture of it. – shurrok Jan 11 '17 at 13:28
1

When used on an array, sizeof returns the number of elements in that array multiplied by the size of each array, as you may see below.

int a[10];
sizeof(a); /* returns (sizeof(int) * 10) */

See here for an example of this code at work.

However, when you assign T1, T2, T3, T4,and T5 as elements of TAB, they are converted to float*, and the information on them being an array is not present in TAB. Consequently, when sizeof is called with the argument TAB[i], it is only interpreted as a pointer to a float, and sizeof(float*) is returned.

ilim
  • 4,477
  • 7
  • 27
  • 46
0

you have to keep track of it yourself. in GCC, follow extension is supported:

struct sized_array {
  int size;
  float array[0];
}

it's called zero length array. and it's how you allocate the memory:

int target_size = 100;
struct sized_array *the_array = malloc(sizeof(struct sized_array) + target_size * sizeof(float));
the_array->size = target_size;

and the_array automatically contains an array with (at least) 100 float slots. more details you can refer to info gcc, 6.17.

Jason Hu
  • 6,239
  • 1
  • 20
  • 41
  • Don't use compiler extensions if there are identical standard ways. The gcc documentation itself notest that this is deprecated in forvour of the standard FAM. And this does not answer the question. – too honest for this site Jan 11 '17 at 13:29
  • @Olaf my gcc doc indicates no deprecation of zero length array. in fact, it elaborates the difference between zla and fam, and the latter, for example, doesn't have a complete type. what's your version of documentation? – Jason Hu Jan 11 '17 at 13:35
  • At least since 4.9.3, it states "In ISO C99, **you would use** a flexible array member, which is slightly different in syntax and semantics:" (C99 should read "C99 and newer" actually, they have not changed that sentence since first appearance). I don't intend to digg deeper, but I know it was ther in 4.6, too; if you use an older compiler than 4.9.3, you definitively should upgrade. The different semantics don't matter, but make it actually more correct for usage. Your zero-length array invokes UB for instance. Note that C standard is C11. – too honest for this site Jan 11 '17 at 13:41
  • @Olaf https://gcc.gnu.org/onlinedocs/gcc-6.3.0/gcc/Zero-Length.html#Zero-Length there is no a word indicating deprecation in the latest doc. i read `you would use` as `you can also use as an alternative but mind the differences`, hence no superiority between both. i also explicitly stated it's a gcc expansion, which is a part of the side knowledge which completes info didn't mention in other answer. i don't see it deserves a downvote. – Jason Hu Jan 11 '17 at 13:42
  • "would use" is much stronger than "may/can". Nevertheless, you cannot use zero-length arrays for anything else than dynamic allocation anyway! And for the part shown, a FAM will do fine. Don't use dirty hacks, with modern compilers like gcc which optimise very agressively, this easily breaks your code if you exploit UB. And, again: **this is not the point of the question**! It does not even use a `struct`!. – too honest for this site Jan 11 '17 at 13:46