0

The program is expected to print each char of the string array.

#include <iostream>
#include <string>

using namespace std;
int main()
{
    const char* numbers[10]{"One", "Too",   "Three", "Four", "Five",
                "Six", "Seven", "Eight", "Nine", "Zero"};

    /*  This version did not work. Why?
           for (const char** ptr = numbers; *ptr != nullptr; *ptr++) {
                const char* pos = *ptr;
                while (*pos != '\0')
                    cout << *(pos++) << " ";
            }
    */
    for(unsigned int i = 0; i < sizeof(numbers) / sizeof(numbers[0]); ++i)
    {
        const char* pos = numbers[i];
        while(*pos != '\0')
            printf("%c ", *(pos++));
        printf("\n");
    }
    return 0;
}

I am aware that my code is a mixture of C++17 and C(in a transition from C to C++, nullptr, cout are two examples), but not sure the first for-loop with

for (const char** ptr = numbers; *ptr != nullptr; *ptr++)

is correct or not. What's wrong with it? Is there a "best practice" to looping thru array of string(char array , not string object yet), especially with the double pointer I'd like to catch, in this case? Thanks!

5
  • Consider putting together a minimal reproducible example that actually compiles. Commented Sep 11, 2021 at 5:08
  • Thanks! You are really fast! Post has been edited with full code. Commented Sep 11, 2021 at 5:18
  • Arrays have length, they are not ended by any marker such as NULL or alike. Add an approriate ending marker by yourself. Commented Sep 11, 2021 at 5:29
  • 1
    The term "double pointer" is ambiguous, and most accurately refers to type double*. I suggest using the term "pointer to pointer" instead (as suggested by the pointer-to-pointer tag description). Commented Sep 11, 2021 at 8:48
  • I read comments about "pointer-to-pointer" in other places too. I'll try to use as suggested. Commented Sep 11, 2021 at 14:58

3 Answers 3

3

Two things -

First, in this loop expression, you don't need to dereference the ptr after incrementing it - *ptr++.

for (const char** ptr = numbers; *ptr != nullptr; *ptr++)
                                                  ^^

*ptr++ will be grouped as - *(ptr++), which means, (post)increment the ptr and dereference the result of (post)increment. It should be just ptr++, as we need the ptr pointer to point to next element in the numbers array after executing the loop body.

Second, if your loop condition is checking for nullptr then the array, which loop is iterating, should have nullptr as a marker to indicate the end of array and you need to increase the size of array as well to adjust end marker:

     const char* numbers[11] {"One", "Too", "Three", "Four", "Five",
                              "Six", "Seven", "Eight", "Nine", "Zero", nullptr};

With the above mentioned changes, the following loop should print the numbers array strings:

       for (const char** ptr = numbers; *ptr != nullptr; ptr++) {
           const char* pos = *ptr;

           while (*pos != '\0')
               cout << *(pos++) << " ";

           cout << "\n";
       }

Since, you have added a new element in the numbers array to mark end of array, be cautious, in the second loop, you are doing sizeof(numbers)/sizeof(numbers[0]) to get the array size and it will give 11 and second loop will end up accessing the nullptr which will be undefined behaviour. Either subtract 1 from sizeof result in loop condition or add a check pos != nullptr before processing it.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks a lot for the elaboration on ptr++. I take yours as answer.
0

In your first loop you a looking for ‘nullptr’ in your array, but you didn’t put it there.

You are reading uninitialized garbage after you array.

I suggest to use std::vector or std::array

1 Comment

Thanks for pointing out 'nullptr' not in the array. Added NULL to the array, for( const char** p2 = numbers; *p2 != NULL; *p2++) { ...} still segfault.
0

Try these edits and see what happens

const char* numbers[11]{"One", "Too", "Three", "Four", "Five", 
                                    "Six", "Seven", "Eight", "Nine", "Zero", NULL};

and

;i < sizeof(numbers)/sizeof(numbers[0])-1;

in the second for loop

Basically *ptr points to the beginning of the respective string. But after last one, it goes out-of-bound. If you really have to compare to nullptr the above is the way to do.

EDIT

Yeah, in addition to the above, ptr should be incremented instead of *ptr. *ptr will be traversing over the string rather than that array.

4 Comments

The pure C part is working. But my question is about the for-loop part with double pointer that I am struggling with.
@Yifangt Did you tried with the edits ? The -1 after sizeof will not change anything. It is there because there is 1 extra element in the array now.
Yes, I tried the -1 for the commented part. Still segfault. I think the problem is with the *ptr++ in the for loop, cf answer by H.S. Thanks anyway.
@Yifangt Yeah I missed that. Also, -1 is not for the commented loop but the second loop

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.