1
#include <iostream>

using namespace std;
char* input(char **S);
int main()
{
    char **S = new char *; 
    char *K = input(S);
    //cout << K << endl;
    cout << *K << endl;
}

char* input(char **S)
{
    cout << "Enter string: ";
    cin >> *S;
    cout << S << endl; // Prints address of S
    cout << *S << endl; //Prints content of address stored in S
    return *S;
}

I am failing to understand why when I print out *K, I just get the first character of the input string but if I print out the commented line(just K alone) I get the whole string. Any help with explaining what I am not able to see or understand is appreciated.

Ken White
  • 123,280
  • 14
  • 225
  • 444
Ron
  • 23
  • 3
  • 2
    You need to read a textbook on basics, where it explains how strings work in C and C++ inherited that. – Slava Jan 18 '22 at 04:38
  • 2
    This code invokes *undefined behavior*. That it prints *anything* is left to pure chance and the (mis)fortunes of blind luck. `S` holds the address of an indeterminate pointer to char. That indeterminate pointer is eventually used as the target for a stream string-read, which invokes UB. After that, spin the whacky wheel of mayhem. – WhozCraig Jan 18 '22 at 04:40
  • 1
    Avoid a lot of pain and just use std::string to work with strings. In this case you only allocated memory for a (char*) but did not allocate memory to store the actual string. Really just use : std::string input; std::cin >> input; and you're done. – Pepijn Kramer Jan 18 '22 at 05:16

1 Answers1

2

Let's understand how arrays work:

// Let's say I have one character array
char arr[] = {'a', 'b', 'c', 'd'};

In here, the name of the array i.e. arr acts as the pointer to the first element of the array. However, do note that it is NOT the pointer to the first element to avoid confusion, it just have an implicit conversion to pointer of element type. More details can be found here: https://stackoverflow.com/a/1641963/10821123

Now since array is contiguous, the rest of the elements can be determined.

// so ideally, the below two statements would print the same thing
cout << &arr << endl;
cout << (void*) &arr[0] << endl;
// the above line just takes out the address of the first pointer

Now coming to your question, I'll convert my example to a string one:

char *K = "abc";

cout << *K << endl; // a
cout << K << endl; // abc

Note that the above assignment of char *K = "abc"; will give you a warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]

The pointer only holds the address of the first element of the array, so when you dereference the pointer, it prints the first element, i.e. *K is interpreted as K[0]

Now there's an overload of operator <<, so what it does is if it sees a character pointer i.e. char*, it prints the complete null-terminated string, that's why in your case too, it is printing the whole string.

Vaibhav
  • 346
  • 2
  • 12
  • "the name of the array i.e. arr is the pointer to the first element of the array" no it is not, and I suggest you fix your answer before you get too many downvotes for this statement. – Slava Jan 18 '22 at 05:08
  • @Slava Thank you for your feedback, I have corrected my answer. Please let me know if I need to fix anything else. – Vaibhav Jan 18 '22 at 05:27