sbsp
sbsp

Reputation: 109

Basic help needed with pointers (double indirection)

I asked some time ago on an account I can't remember how to manipulate basic pointers and someone gave me a really good demo

for example

char *ptr = "hello" (hello = a char array)

so now *ptr is pointing at 'h'

ptr++ means moving the ptr to point at the next element, to get its value I do *ptr and that gives me e


ok so far everything works as I hope :D, but now I need to manipulate a char **ptr and was wondering how I do this in a way that mimics the effects of a 2d array?

Some basic tips would be much appreciated as I need to do an assignment that has a **ptr to imitate a 2d array and without knowing how it does this first means I can't even solve it on paper (for example, how do you dereference a **ptr, how do you get [x][y] values etc)

thanks

Upvotes: 3

Views: 4961

Answers (3)

John Bode
John Bode

Reputation: 123578

You can subscript a pointer the same way you can subscript an array, provided all the addresses have been set up correctly.

Assuming the following declaration:

char **ptr;

here are the types of the various expressions:

       Expression        Type      Equivalent expressions (yield same value)     
       ----------        ----      -----------------------------------------
              ptr        char **   &ptr[0]
             *ptr        char *    ptr[0] 
         *(ptr+i)        char *    ptr[i]; &ptr[i][0]
            **ptr        char      ptr[0][0]
      *(*(ptr+i))        char      ptr[i][0]; *ptr[i]
    *(*(ptr+i)+j)        char      ptr[i][j]

thus:

  • ptr can be treated as though it was an array of strings (2-d array of char)
  • ptr[i] points to the beginning of the i'th string in the list
  • ptr[i][j] is the value of the j'th character of the i'th string in the list
  • The expressions ptr++ and ++ptr will advance ptr to point to the next string
  • The expressions (*ptr)++ and ++(*ptr) will advance *ptr to point to the next character

As for setting up your pointers, this arrangement assumes everything has already been allocated as static arrays or dynamically through malloc. You cannot just write

char **ptr = {"foo", "bar", "bletch"}; // using aggregate initializer on 
                                       // non-aggregate type; bad juju,
                                       // a.k.a undefined behavior

or

char **ptr;          // ptr has not been initialized to point anywhere 
ptr[0] = "foo";      // dereferencing ptr via subscript invokes undefined
ptr[1] = "bar";      // behavior
ptr[2] = "bletch";

Generally, when you're using a pointer as though it was an array, you'll use malloc or something similar to allocate your buffers:

char **ptr = malloc(sizeof *ptr * N);
if (ptr)
{
  ptr[0] = "foo";    // ptr[i] gets address of
  ptr[1] = "bar";    // string literal
  ptr[2] = "bletch";
  ...
}

or

char **ptr = malloc(sizeof *ptr * N);
if (ptr)
{
  size_t i;
  for (i = 0; i < N; i++)
  {
    ptr[i] = malloc(sizeof *ptr[i] * M); // strictly speaking, the sizeof
    if (ptr[i])                          // is not necessary here
    {
      //initialize ptr[i]
    }
  }
}

Upvotes: 10

Max Shawabkeh
Max Shawabkeh

Reputation: 38653

A pointer to a pointer is just that. For example:

// Declare our double-indirection pointer.
char** ptr;
// And initialize it:
char s1[] = "hello";
char s2[] = "world";
ptr = malloc(sizeof(char*) * 2);
ptr[0] = s1;
ptr[1] = s2;
// ptr now points to a pointer that points to 'h'.
char* ptr2 = *ptr;
// ptr2 points to 'h'.
char* ptr3 = *(ptr + 1);
// ptr3 points to "w".
char c = **ptr; // could be written as *(*ptr)
// c = 'h'.
char c2 = *(*(ptr + 1));
// c2 = 'w'.
char c3 = *(*(ptr) + 1);
// c3 = 'e'.

Upvotes: 4

Ish
Ish

Reputation: 338

You may use them as you would a normal two-dimensional array. (Since effectively, that's what they are)

char** ptr = {"lorem", "ipsum", "dolor"};
char* s1 = ptr[0]; //Points to the beginning of "lorem"
char* s2 = ptr[1]; //Points to the beginning of "ipsum"
char c = ptr[2][4]; //Contains 'r'

This is due to the fact that:

int *a;
//...
int i = a[6];
int j = *(a + 6); //Same as previous line!

Cheers,

Amit Ron--

Upvotes: 1

Related Questions