S.Sot
S.Sot

Reputation: 323

Pointing to a double pointer

I am writing a function which takes a double pointer as a parameter. I noticed that expressions like this char *tmp = arr[i]; work, where arr is a char **arr pointer. The whole function looks like this :

void string_sort(char** arr,const int len,int (*cmp_func)(const char* a, const char* b))
{
    for (int i = 0; i < len; ++i)
    {
        for (int j = i + 1; j < len; ++j)
        {
            if(cmp_func(arr[i], arr[j]) > 0)
            {
                char *tmp = arr[i];
                arr[i] = arr[j];
                arr[j] = tmp;
            }
        }
    }
}

My question is - why is arr[i] considered an address and not a dereferenced pointer? (I understand that a double pointer "points" to another pointer's address, but I don't understand why this syntax is valid). Can you give an example of an equivalent expression without an array-like syntax?

Upvotes: 1

Views: 224

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 310940

Here you are

#include <stdio.h>

int main(void) 
{
    char *s = "Hello";

    printf( "%p -> %s\n", ( void * )s, s );

    char **t = &s;

    printf( "%p -> %p ->  %s\n", ( void * )t, ( void * )*t, *t );
    printf( "%p -> %p ->  %s\n", ( void * )t, ( void * )t[0], *t );

    return 0;
}

The program output might look like

0x55a06f99c004 -> Hello
0x7ffc051a83d8 -> 0x55a06f99c004 ->  Hello
0x7ffc051a83d8 -> 0x55a06f99c004 ->  Hello

That is the pointer s points to the first character of the string literal "Hello".

The pointer t points to the pointer s that in turn points to the first character of the string literal "Hello".

For example if you have a declaration like this

char *s = "Hello";

then the both expression s[0] and *s have the type char and yield the first character of the string literal that is 'H'.

Another example. If you have an array of integers

int a[] = { 1, 2, 3, 4, 5 };

then the number of its elements can be calculated either like

sizeof( a ) / sizeof( a[0] )

or like

sizeof( a ) / sizeof( *a )

[Though you may even write like

sizeof( a ) / sizeof( a[1000] )

because the used expression is not evaluated. It is important only the size of an object of the type int. SO you could also write

sizeof( a ) / sizeof( int )

-end note]

Upvotes: 1

ForceBru
ForceBru

Reputation: 44828

This syntax is valid because arr[i] is literally the exact same as *(arr + i). This is also an example without using array subscript syntax, BTW.

...why is arr[i] considered an address and not a dereferenced pointer?

Yes, arr[i] is a dereferenced pointer, as discussed above. It's also an address because when you dereference a pointer to a pointer (char **arr), you get a pointer - an address.

Upvotes: 2

Related Questions