0

For the given code below : If we place name inside main, I get a segmentation fault. Why? Can we print each element of the matrix using p? Why does p++ jump by 8 bytes, while cp++ jumps to the next string?

char *name[] = {"Arza", "Homes"};   //NULL is added as the third-string? If this line goes into main, segfault?

int main(int argc, char *argv[]){

    int matrix[][4] = {{1,2,3,4}, {5,6,7,8}, {9, 10, 11, 12}, {13, 14, 15, 16}};

    int i,j,*d,**p;     //can we print each element of matrix using p?

    d =  p = matrix;

    for(i = 0; i < 4; i++){
        printf("darray[%d] = { ",i);
        for(j=0;j<4;j++)    {
            printf(" 0x%X %d ",*d++, *p++);  //Why does p jump 2 ints?              
        }
        printf("}\n");
    }

    char ** cp;
    cp = name;
    printf("Name is : ");
    while(*cp) 
        printf("%s ",*cp++);        //how does cp jump to next string no matter the size of each string?
}
Andro
  • 2,232
  • 1
  • 27
  • 40
  • `matrix` on access is type *pointer-to-array-of-int* `[4]`, (e.g. `int (*)[4]`) not `int**`. `d = p = matrix;` is incorrect.`Helpful [How does de-referencing work for pointer to an array?](https://stackoverflow.com/questions/56280487/how-does-de-referencing-work-for-pointer-to-an-array/56280581#56280581) – David C. Rankin Nov 21 '19 at 08:14
  • See also [what is the difference between *pt in int (*pt)\[2\] and pt in int *pt?](https://stackoverflow.com/questions/58151924/what-is-the-difference-between-pt-in-int-pt2-and-pt-in-int-pt) – David C. Rankin Nov 21 '19 at 08:20
  • In C, if you increment a pointer, it increments by the size of the data type it points to. This is so that it points to the very next data item after an increment. If you have a pointer to a pointer, then it increments by the size of a pointer, in this case 8 bytes (addresses are 64-bit values). – lurker Nov 21 '19 at 08:25
  • This code generates warnings with GCC: `prog.c:9:12: warning: assignment to 'int **' from incompatible pointer type 'int (*)[4]' [-Wincompatible-pointer-types] 9 | d = p = matrix;` And of course GCC is right... `p` has type `int**` while `d` has type `int*`. Hence the line `d = p = ...` is wrong. – Bktero Nov 21 '19 at 08:54
  • d++ points to the next element as its a consecutive mem. what should p++ do? – arzahomes Nov 21 '19 at 09:00
  • `p` is a *pointer-to-pointer*. What is `sizeof (a_pointer)`? That is how many bytes after the initial `p++` will point. Always compile with *warnings enabled*, and **do not** accept code until it *compiles without warning*. To enable warnings add `-Wall -Wextra -pedantic` to your `gcc/clang` compile string (also consider adding `-Wshadow` to warn on shadowed variables). For **VS** (`cl.exe` on windows), use `/W3`. All other compilers will have similar options. Adding `-Werror` to treat warnings as errors may emphasize this point. – David C. Rankin Nov 21 '19 at 09:03
  • Unless you would use a function such as `calloc` or the `static` keyword in your variable declaration then the data would not be initialized to zero. – C. R. Ward Nov 21 '19 at 19:31

2 Answers2

0

Seems that you have some troubles with pointers. Your name array is an array of pointers to pointers

char *name[] = {"Arza", "Homes"};

I put it into the main and changed the structure of the printing loop a little bit:

for(int i = 0; i < (sizeof(name) / sizeof(name[0])); i++)
        printf("%s ",*(cp++));

In your code while loop started to operate with memory you don't have acces to. Now the segmentation fault doesn't occur because the loop stops when i counter is equal to the size of your name array (size of the whole array divided by an array element).

Your p jumps 2 integers because p and d are pointers and you have them pointed to the same "cell" of memory:

d =  p = matrix;

and they can change it, so when d value is incremented p value is incremented too because they address to the same piece of memory. You should initialize p as an integer and give it the value of your matrix:

d = matrix;
p = **matrix;

I hope now it works. Here you have some info about pointers in C.

Excuse me if I said something wrong :).

Sinking
  • 95
  • 8
0

//NULL is added as the third-string? If this line goes into main, segfault?
no, name is an array, not a string. So the while in main() does not work. use i < sizeof(name) instead;

//Why does p jump 2 ints?
sizeof(pointer) is 8 on a 64-bit machine. p++ is p+sizeof(int*), d++ is d+sizeof(int).
Try printf sizeof(int), sizeof(int*), sizeof(int**).
By the way, matrix is not an array of pointers.

//how does cp jump to next string no matter the size of each string?
cp is a pointer points to a pointer points to a string, cp++ moves to next position (here is cp + sizeof (char*)), it has things to do with what it points to, and has nothing to do with what sub-level-pointer points to.

Link
  • 118
  • 6