cin >> (pointer to char);

Pages: 12
when I cin a pointer to char, I create an array of chars. Why does this work? Is this 'undefined' behavior? Is this natural? Am I actually just

1
2
3
4
5
6
7
8
9
10
11
#include <iostream>

int main(){
  char * str;
  char c;
  std::cin >> str;
  for(int i = 0;str[i] != '\0';i++){
    c = str[i];
    std::cout << c;
  }
}
Last edited on
It doesn't work, look deeper into it. Also note that char* also equivalent to void* is just a 32/64 bit number which is an address, to put a value into that address it requires to be allocated, through stack or heap.
But then why is it actually taking my input? I can input "0000" and it will give me back "0000", i know that it shouldn’t work but it is and I want to know what is really happening. If what your saying is true, then why am I getting back a full "0000" instead of just "0"?
Also you can’t cin a void pointer.

Edit: (I just tried) and I was also able to give and receive emojis'&#$%-' with the char pointer.
Last edited on
it "works".
1
2
3
4
5
6
#include <iostream>

int main(){
  void * str;
  std::cin >> str;
}


also try the online compiler, that is my testing ground.

also tried rextester with VS and it does the same result, 0000 = early termination.

edit: (clarification, rextester isn't a great since it doesn't use interactive inputs, I use the compiler associated with this forum, cpp.sh when I need interactiveness or onlinegdb for newer standards)
edit: I mistaken the output data as the input, it does work in VS, and also stops working with /O2.

tell us your compiler and enviroment.

edit: ahh I see the problem here, the web compiler uses optimizations by default, turning them off will make your results appear.

+Yea clang / c++11 / ubuntu, you should have a habit mentioning it in every question you ask.

++Optimizations are part of the command line, it works by putting -O2 in the section where you put -std=c++11 (these are called compiler flags). You can see a big list of them if you had an IDE like codeblocks / eclipse.

overall your mistake is that you didn't listen to the compiler warnings, you should always use -Wall, and it would've told you that you are using uninitialized data.
Last edited on
Ok one sec.
I used repl.it which says


clang version 7.0.0-3~ubuntu0.18.04.1 (tags/RELEASE_700/final)
> clang++-7 -pthread -std=c++11 -o main main.cpp
> ./main

in the console and then obviously runs main.
sry if that’s not actually all the right stuff. Not entirely sure what you mean.
edit: ahh I see the problem here, the web compiler uses optimizations by default, turning them off will make your results appear.
not sure how to or if I even can.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <iomanip>
#include <string>

int main()
{
    {
        // create an array to hold a c string of up to N-1 characters
        const std::size_t N = 16 ;
        char cstr[N] ; // can hold a max of N-1 characters plus a terminating null character

        std::cout << "enter a string of up to a max of " << N-1 << " characters (no spaces): " ;
        // std::setw: we need to place a limit on the number of characters
        std::cin >> std::setw(N) >> cstr ; // we won't accept more than N-1 characters
        // if the user entered a longer string, the unaccepted characters will remain in the input buffer

        std::cout << "you entered " << std::quoted(cstr) << '\n' ;
    }

    {
        // std::string: better, cleaner, saner, safer etc.

        std::string str ; // will expand to hold all the characters entered by the user

        std::cout << "enter a string (no spaces): " ;
        std::cin >> str ; // we accept any number of characters
                          // we could use std::setw here too, if we want to limit the input

        std::cout << "you entered " << std::quoted(str) << '\n' ;
    }
}
Used volatile and the thing exploded (in the right way I’m guessing) about how you can’t cin a char pointer

Edit: is volatile even the right thing??
Last edited on
Volatile is used to suggest to the compiler that the value may be changed by other threads (oversimplified explanation), and doesn't otherwise change the circumstances, though it may not be an overloaded type that's applicable, so it fires off a different reaction from the compiler.

It doesn't "help" what you're proposing the OP.

Yet, I'm curious to understand why? I can't imagine a really good reason.
@JLBorges thank you but this is not a question of "what is best" but of "why the fuck" (sry I didn’t respond before, this site is a tad bit wonky for me at times.)
Gah! Again! I didn’t see niccolo’s post this time! XD ok so I saw off some random place that it makes it so the compiler doesn’t try to optimize any thing about that piece of code, so I just kinda sent up a quick prayer and typed it in and it worked.

Edit: also, there is absolutely no good reason for my code. Only bad ones. Unashamedly bad ones
Last edited on
Well, volatile is said to skip certain optimizations in that it will always load the value from memory, and not re-use a copy of it in a register in multiple reads of the value.

It also is part of the decoration of the type, so it does tend to create a mangled-type-name difference.
Um. Confused but ok I guess. I get the mangled-type-name thingy but the rest is a tad more difficult for me, I kinda get it but not really.
Last edited on
> this is not a question of "what is best" but of "why the fuck"

The program engenders undefined behaviour; the question: "why did it behave this way" is moot.
"Renders the entire program meaningless if certain rules of the language are violated."
https://en.cppreference.com/w/cpp/language/ub

1
2
3
4
5
6
#include <iostream>

int main(){
  char * str;
  std::cin >> str; // this is undefined behaviour
}



> is volatile even the right thing??

volatile (within a single thread of execution, a volatile access cannot be optimised out or reordered relative to another visible side effect):
See: https://en.cppreference.com/w/c/language/volatile#Uses_of_volatile

Compare with atomic (If one thread writes to an atomic object while another thread reads from it, the behaviour is well-defined):
https://en.cppreference.com/w/cpp/atomic/atomic
Oh, ok...here's a better breakdown (I seem to think you're more experienced from your other posts)...

Ok, let's say you have an int.

int a{ 5 };

When I use this int in a series of statements like this:

b = a * 5;
c = a * 2;

In this situation, "a" is read twice. Remember, it has a location in memory. Because of the declaration above, it is on the stack (not allocated dynamically with new).

An optimization step the compiler might issue is to load the value of "a" into a CPU register (internal memory to the CPU). It will use that to perform the multiplication for b =....

Now, for the next multiplication, the value of "a" is already in the CPU register from the previous step. It's already in the "mind" of the CPU, so it just re-uses it. It does not re-read the value from memory, because it already has it "in mind", and saves the step of reading from RAM.

However, imagine that another thread is running. Imagine that it has access to "a" (say I called a function and passed a reference which is now running in that thread).

Both threads can read from "a".

Both threads could write to "a".

What if that second thread changed "a" to, say, 7, just after the multiplication of "b = ", but before the next multiplication?

If the optimizer still used the copy of "a" still "in the mind" of the CPU, then "c = " would still be 5 * 2, not 7 * 2.

If "a" is declared as volatile, the compiler generates code to force the re-read of "a" each time it is used. In essence this means that if another thread changed "a" just after "b = " executes, the next statement would re-load "a", and see the new "7" and not the original "5". It would not use the copy "already in mind".

That's about all that volatile does. It forces the re-read of a value, and denies optimizations that could easily skip that re-read to speed things up.

With respect to your use of a char *, that would make the pointer volatile. All that really means is that where there might be an opportunity to re-use a copy of the pointer already "in the mind" of the CPU, it won't - it will reload it from RAM every time it is used.

It is a very limited change.
Last edited on
Note that volatile variables are not suitable for communication between threads; they do not offer atomicity, synchronization, or memory ordering. A read from a volatile variable that is modified by another thread without synchronization or concurrent modification from two unsynchronized threads is undefined behavior due to a data race.
https://en.cppreference.com/w/c/language/volatile#Uses_of_volatile
Oh ok thanks.
Pages: 12