aurelienC
aurelienC

Reputation: 1183

Trouble with pointers to pointers

i am currently learning pointers and it looks like i can't handle them properly.
So i have an array of strings, which i represent like this:

char** array;

I can print all strings of the array with this function, it works fine:

void write_lines(char** array_of_string)
{
    for(; *array_of_string; array_of_string++)
        printf("%s", *array_of_string);
}

But what i want to do right now is to change the content of the array, to do so i want to use a function that takes a char*** as a parameter:

void write_lines_2(char*** array_of_string)
{
    for(; ***array_of_string; (*array_of_string)++)
       printf("%s", **array_of_string);
}

This function is just a test, to see how i can access the elements properly with a char*** as parameter. And as you could expect it compile but crash when lauched.
Could you explain me how to do it right?

Edit: Eventually the function will swap strings in the array.
I already have a swap(char** string, char** string2) function, that is why i thought i needed a third pointer to change the content of the array passed as parameter and not only change a copy of it.

Edit 2: I tried a few more things and i realized that:

void write_lines(char*** array_of_string)
{
    int length = 3; // array goes from [0] to [3]

    for(i = 0; i <= length; i++) // It works!
        printf("%s", *(*array_of_string + i));

    for(i = 0; i <= length; i++, array_of_string++) // Crash
        printf("%s", **array_of_string);

    for(i = 0; i <= length; i++, array_of_string++); // Doesn't crash

    for(i = 0; i <= length; i++, (*array_of_string)++) // Crash
        printf("%s", **array_of_string);

    for(i = 0; i <= length; i++, (*array_of_string)++); // Crash
}

I guess i should be using (*array_of_string)++ to change which string is pointed, because array_of_string++ would change which array is pointed, but i am not sure. Anyway, even if i can build the function an other way, this is just an exercice so what matter for me is to understand why what i am trying to do doesn't work and i still dont know why.

Upvotes: 1

Views: 99

Answers (3)

erip
erip

Reputation: 16985

Your code seems to terminate on a null character - it seems you want it to terminate on a NULL string. You'll want to make the following change:

void write_lines(char** array_of_string)
{
    // remove one dereference in the terminating condition of the loop
    for(; *array_of_string; array_of_string++)
        printf("%s", *array_of_string);
}

To make it more readable, I might write it the following way by passing the size of the array instead of worrying about NULL terminating the array:

#include <stdio.h>

#define SIZE 2

// Note that I'm passing the char** and the size.
void write_lines(char** arr, size_t n) {
  if(!arr) return;

  for(size_t i = 0; i < n; ++i) {
    printf("%s\n", arr[i]);
  }
}

int main() {
   char* strings[SIZE] = { "Hello", "World" };
   write_lines(strings, SIZE);

   return 0;
}

Upvotes: 1

Sergey Kanaev
Sergey Kanaev

Reputation: 592

First of all, the frst function should look like this:

void write_lines(char** array_of_string)
{
    // char * = string (pointer to string start)
    // char ** = array of strings
    // the pointer to string start should be valid
    for(; *array_of_string; array_of_string++)
        printf("%s", *array_of_string);
}

Then, you can see, that when function argument becomes char ***pointer_to_array_of_strings then char **array_of_strings = *pointer_to_array_of_strings. And then you can act the same as in write_lines. The fault was in (*pointer_to_array_of_string)++ as it will shift array_of_strings by sizeof(char **).

P.S.: It is a little of mess here with pointer_to_array_of_strings and array_of_strings. Here I use former to indicate char *** and the latter to indicate char **.

Upvotes: 1

pm100
pm100

Reputation: 50210

this is slightly odd

void write_lines(char** array_of_string)
{
    for(; **array_of_string; array_of_string++)
        printf("%s", *array_of_string);
}

It says that the end of the array is an empty string. I think you really want

void write_lines(char** array_of_string)
{
    for(; *array_of_string; array_of_string++)
        printf("%s", *array_of_string);
}

It says that the end of the array is a null pointer. This is much more normal (for a start it allows empty lines in the array)

Upvotes: 4

Related Questions