-2

Why can I create an array of pointers and dereference its (pointer-)elements.

int a = 1;
int* arr[1];

arr[0] = &a;

But cannot do the same with pointer to pointers:

int** arr2;
arr2[0] = &a;
--> Seg fault
ChiefHan
  • 19
  • 2
  • You did not allocate any memory where your pointer pointer would point to and the pointer is uninitialized, so this is undefined behavior. – Bodo Feb 23 '21 at 15:54
  • When you create an array, the memory is implicitly allocated on the stack so you can access it immediately. When you want to use a pointer, you need to allocate the memory yourself by using `arr2 = malloc(sizeof(int*))`. – apilat Feb 23 '21 at 16:18

2 Answers2

1

int** arr2;

You don't initialize this pointer. Accessing it is undefined behavior and can/will result in crashes.

To initialize use something like int** arr2 = malloc(<someSize> * sizeof(*arr2)). (PS: malloc may return NULL, and you have to use free to return the memory).

JCWasmx86
  • 3,473
  • 2
  • 11
  • 29
  • Thanks! The pointer `arr2` is still stored in the Stack? Only pointing to the heap where my int Pointers will be stored...? – ChiefHan Feb 23 '21 at 16:11
  • No. It's on the heap – JCWasmx86 Feb 23 '21 at 16:12
  • @ChiefHan If the variable `int** arr2;` is a local variable inside a function, the pointer variable itself will be on the stack, i.e. the memory location where the address returned by `malloc` will be stored. The pointer points to the heap where the data assigned to the array element(s) will be stored. – Bodo Feb 23 '21 at 16:43
1

from the first part

int a = 1;
int* arr[1];
arr[0] = &a;

So a is int. arr is what? It is int*[], an array of pointers to int. So the first and only element arr[0] is a pointer to an int and it is normal to assign an address of an int to it. The compiler is ok with that, since the operator & --- Address of --- assigns the address of the int a to a pointer to int, arr[0].

from the second part

    int** arr2;
    arr2[0] = &a;

arr2 is what? It is int**, a pointer to a pointer to int.

  • arr2 is int**
  • so *arr2 is int*, a pointer to an int
  • and **arr is an int

arr2 is NOT what? NOT an array, so you can not write as you did arr[0].

what you can write instead

arr2 is int** so as in the first case it can get the address of a pointer to int. And you have an array of these here in the first part. So you for sure can write

    arr2 = &arr[0];

Since & will extract the address of a pointer, and arr[0] is a pointer to int. And arr2 is int**, a pointer to a pointer to int.

See the output

toninho@DSK-2009:~/projects/um$ gcc -o tst -Wall -std=c17 pp.c
toninho@DSK-2009:~/projects/um$ ./tst
*arr[0] = 1 and **arr2 = 1
toninho@DSK-2009:~/projects/um$ 

of this code

#include <stdio.h>

int main()
{
    int     a = 1;
    int*    arr[1]; // so arr is what? int*[]

    arr[0] = &a;

    int**   arr2; // arr2 is what? int**
    //arr2[0] = &a;

    arr2 = &arr[0];

    printf("*arr[0] = %d and **arr2 = %d\n",
        *arr[0], **arr2 );
    return 0;
};
arfneto
  • 1,227
  • 1
  • 6
  • 13
  • Why can't I write `arr2[0]`? Since `x[y] == *(x + y)`, we would get `*(arr2 + 0) == *arr2`. As you said: `*arr2` ist an `int*`. I think the problem was (as mentioned by the previous comment) that I tried to dereference some kind of reserved memory because I didn't initialize my int** --> segmentation fault – ChiefHan Feb 23 '21 at 17:17
  • read the code I posted at the end and compare. *arr2 is int* so it must, as I told you, point to a pointer. And you can as I showed you, use arr2 = &arr[0]. arr2 is int** not an array. Did you read the full text? – arfneto Feb 23 '21 at 17:47
  • did you run the program I posted in your machine? Compared to your code? – arfneto Feb 23 '21 at 17:47
  • Well, it is true that you did not initialize arr2. You tried in the wrong way. I showed you one legal way. Sure you can write `*arr2 = malloc(sizeof(int))`, and then assign something to it. And then free() it at the end. But is is not the point. The point is understand the mechanics of doing that and what is what, int*[] and int** for example. – arfneto Feb 23 '21 at 17:52