Differences when using ** in C

前端 未结 11 957
半阙折子戏
半阙折子戏 2020-12-24 10:50

I started learning C recently, and I\'m having a problem understanding pointer syntax, for example when I write the following line:

int ** arr = NULL;
         


        
11条回答
  •  滥情空心
    2020-12-24 11:31

    Having solely the declaration of the variable, you cannot distinguish the three cases. One can still discuss if one should not use something like int *x[10] to express an array of 10 pointers to ints or something else; but int **x can - due to pointer arithmetics, be used in the three different ways, each way assuming a different memory layout with the (good) chance to make the wrong assumption.

    Consider the following example, where an int ** is used in three different ways, i.e. p2p2i_v1 as a pointer to a pointer to a (single) int, p2p2i_v2 as a pointer to an array of pointers to int, and p2p2i_v3 as a pointer to a pointer to an array of ints. Note that you cannot distinguish these three meanings solely by the type, which is int** for all three. But with different initialisations, accessing each of them in the wrong way yields something unpredictable, except accessing the very first elements:

    int i1=1,i2=2,i3=3,i4=4;
    
    int *p2i = &i1;
    int **p2p2i_v1 = &p2i;  // pointer to a pointer to a single int
    
    int *arrayOfp2i[4] = { &i1, &i2, &i3, &i4 };
    int **p2p2i_v2 = arrayOfp2i; // pointer to an array of pointers to int
    
    int arrayOfI[4] = { 5,6,7,8 };
    int *p2arrayOfi = arrayOfI;
    int **p2p2i_v3 = &p2arrayOfi; // pointer to a pointer to an array of ints
    
    // assuming a pointer to a pointer to a single int:
    int derefi1_v1 = *p2p2i_v1[0];  // correct; yields 1
    int derefi1_v2 = *p2p2i_v2[0];  // correct; yields 1
    int derefi1_v3 = *p2p2i_v3[0];  // correct; yields 5
    
    // assuming a pointer to an array of pointers to int's
    int derefi1_v1_at1 = *p2p2i_v1[1];  // incorrect, yields ? or seg fault
    int derefi1_v2_at1 = *p2p2i_v2[1]; // correct; yields 2
    int derefi1_v3_at1 = *p2p2i_v3[1]; // incorrect, yields ? or seg fault
    
    
    // assuming a pointer to an array of pointers to an array of int's
    int derefarray_at1_v1 = (*p2p2i_v1)[1]; // incorrect; yields ? or seg fault;
    int derefarray_at1_v2 = (*p2p2i_v2)[1]; // incorrect; yields ? or seg fault;
    int derefarray_at1_v3 = (*p2p2i_v3)[1]; // correct; yields 6;
    

提交回复
热议问题