C++: Unexplainable behavior with cout and pointer to char [duplicate] - c++

This question already has answers here:
Why is address of char data not displayed?
(8 answers)
Closed 6 years ago.
After printing a pointer to an int, I print a pointer to a char:
#include <iostream>
using namespace std;
int main() {
int i;
cout << "&i: " << &i << endl;
char q = 'q';
cout << "&q: " << &q << endl;
return 0;
}
I get the following output as expected:
&i: 0xffffcc0c
&q: q
However, if I comment out cout << "&i: " << &i << endl;, and run the program again, I get the following unexplained output:
&q: q����
Does anyone know why this is happening?
If it has to do with operator<< inserting into the stream until it finds a null character, then why do I get the expected output when I include cout << "&i: " << &i << endl;?
NOTE: I am not expecting to get the address of q from cout. I am expecting to get the C string pointed to by &q. What bugs me is how the output just prints the 'q' if I include the line cout << "&i: " << &i << endl; beforehand. However, if I comment that line out, there is garbage data in the output. Why is there not garbage data in my output when I include the line cout << "&i: " << &i << endl;?

The bit &q thinks it is a string.
Therefore will print up to the null character. hence the extra output

Related

Unexpected result for "&array" [duplicate]

This question already has answers here:
Why are `&array` and `array` pointing to the same address?
(2 answers)
How come an array's address is equal to its value in C?
(6 answers)
Closed 1 year ago.
I am confused about array usage as pointer and result of that. Let me explain. When I try this
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int *myPointer = &a;
cout << "*myPointer: \t" << *myPointer << endl;
cout << "myPointer: \t" << myPointer << endl;
cout << "&myPointer: \t" << &myPointer << endl;
cout << "myPointer[0]: \t" << myPointer[0] << endl;
cout << endl;
int myArray[3] = {1,2,3};
cout << "*myArray: \t" << *myArray << endl;
cout << "myArray: \t" << myArray << endl;
cout << "&myArray: \t" << &myArray << endl;
return 0;
}
All of output are exactly what I expected, except last one (&myArray). Lets say my ram something like this:
Address
Variable
Value
0xA100
a
10
0xA101
myPtr
0xA100
0xA102
1
0xA103
2
0xA104
3
0xA105
myArray
0xA102
If I imagine it correctly, then how "&myArray" can be same with "myArray"? Actually, I think it can be anything but 0xA102. Because, this result means that "myArray" is in 0xA102 and value of pointed by myArray is in 0xA102 too. And I know it is weird but it means also, as a value "1", is in 0xA102 too. (At least I got it from this result).
So, I cannot catch the point. I think the result has to be 0xA105 if "&" means address. If yes, why result is not 0xA105. If not, why they have different usage although arrays are pointers.
Is there anybody can clarify the matter?
Thanks.

How to print from the beginning after endl in C++? [duplicate]

This question already has answers here:
Clearing terminal in Linux with C++ code
(4 answers)
Closed 6 years ago.
I am currently trying to print some thing on the console. Similar to loading in same line using "\r" but instead I have endl included.
#include <iostream>
int main(int argc, char **argv)
{
int x = 3;
// first part
std::cout << " x = " << x <<"\n";
std::cout << " y = " << x <<"\n";
std::cout << " z = " << x << "\n";
std::cin >> x ;
std::cout << "\r" << std::flush;
// second part
std::cout << " x = " << x <<"\n";
std::cout << " y = " << x <<"\n";
std::cout << " z = " << x <<"\n";
return 0;
}
The above code prints the first part and prints again the second part in different place. So the total column is eight. What I actually want is to print the first part take input from user and then replace the first part with second part. This way total column is 3.
You can write the backspace character '\b' to move backwards on your line. This only moves your cursor so you'll have to hen write your content after you have backed up.
To move up you can use '\e[A' and '\e[B' to move down.
Note: This solution is not very portable, but if it works for your situation go for it!
You may also want to look into system specific functions if you want to move multiple lines or clear the entire screen.

Effects of modifying std::string using op[] beyond its size?

I'm bit puzzled by how modifying a std::string beyond its size is handled? In an example I tried, it allowed me to modify the string beyond its size using op[] (and I'm aware that standard doesn't stop you from doing it). However, when I print the string using cout it prints the original string but when I print whats returned by cstr (), it prints the modified version. How does it keep track of both sizes (3 & 5)?.
#include <string>
#include <iostream>
using namespace std;
int main(void) {
std::string a = "abc";
cout << "str before : " << a << endl;
const char * charPtr = a.c_str ();
cout << "c_str before : " << charPtr << endl;
cout << "str size / capacity : " << a.size () << ", " << a.capacity () << endl;
a[3] = 'd';
a[4] = 'e';
cout << "str after : " << a << endl;
const char * charPtr2 = a.c_str ();
cout << "c_str after : " << charPtr2 << endl;
cout << "str size / capacity : " << a.size () << ", " << a.capacity () << endl;
return 0;
}
output :
str before : abc
c_str before : abc
str size / capacity : 3, 3
str after : abc
c_str after : abcde
str size / capacity : 3, 3
Although you already got a correct comment saying the behaviour is undefined, there is something worthy of an actual answer too.
A C++ string object can contain any sequence of characters you like. A C-style string is terminated by the first '\0'. Consequently, a C++ string object must store the size somewhere other than by searching for the '\0': it may contain embedded '\0' characters.
#include <string>
#include <iostream>
int main() {
std::string s = "abc";
s += '\0';
s += "def";
std::cout << s << std::endl;
std::cout << s.c_str() << std::endl;
}
Running this, and piping the output through cat -v to make control characters visible, I see:
abc^#def
abc
This explains what you're seeing: you're overwriting the '\0' terminator, but you're not overwriting the size, which is stored separately.
As pointed out by kec, you might have seen garbage except you were lucky enough to have an additional zero byte after your extra characters.

C++ string pointer doesn't have the same memory address as the string it points to

I wrote a simple program to see how C++ handles pointers to string objects (new to OOP), and I was suprised to see that string* as which was assigned the memory address of string a, didn't store a value equivalent to &a. Also, the console didn't print the value to *as. Could this be an error on my end or the system, or am missing something fundamental here?
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
string a = "asdf";
string* as = &a;
string* as_holder = &a;
int main()
{
cout << "a = " << a << "\t" << "&a = " << &a << " *as = " << *as << endl
<< "as = " << as << endl
<< "++as = " << ++as << endl
<< "*as = " << *as << endl << endl;
return 0;
}
output:
a = asdf &a = 011ff68C *as =
as = 011FF6A8
++as = 011FF6A8
*as =
In my test of the valid portion of your program (the first two lines of cout), the printout showed the same address:
a = asdf &a = 0x8049c90 *as = asdf
as = 0x8049c90
(link to a demo)
Lines three and four, however, amount to undefined behavior: once you do ++as, you are moving the pointer to the next std::string in an "array of strings" (which does not exist). Therefore, the subsequent attempt at dereferencing as is undefined behavior.
If you would like to obtain a pointer to the data of your string, such that you could move to the next character by incrementing the pointer, you could use c_str() member function, like this:
const char *as = a.c_str();
as++;
cout << as << endl; // This would print "sdf"

Accessing char member variable address of a structure

I have a structure and i am trying to print the address of their member variables.
When tried to print the address of char member variable through &(f.c) i am not getting their address.
Here is the code:
struct foo
{
char c;
short s;
void *p;
int i;
};
int main()
{
cout << "Size of foo: " << sizeof(foo) << endl;
foo f;
cout << "Address of c: " << reinterpret_cast<void*>(&f.c) << endl;
cout << "Address of c: " << &(f.c) << endl;
cout << "Address of s: " << reinterpret_cast<void*>(&f.s) << endl;
cout << "Address of s: " << &(f.s) << endl;
cout << "Address of p: " << reinterpret_cast<void*>(&f.p) << endl;
cout << "Address of p: " << &(f.p) << endl;
cout << "Address of i: " << reinterpret_cast<void*>(&f.i) << endl;
cout << "Address of i: " << &(f.i) << endl;
return 1;
}
Output
/pp/cplus/bas ]$ ./a.out
Size of foo: 12
Address of c: 0xffbfe680
Address of c: //----------- &(f.c). Why this is empty..
Address of s: 0xffbfe682
Address of s: 0xffbfe682
Address of p: 0xffbfe684
Address of p: 0xffbfe684
Address of i: 0xffbfe688
Address of i: 0xffbfe688
just want to know why it is not printing when i tried accessing it through &(f.c)
Compiled using gcc version 3.4.6
cout has an operator<< overload for char* which treats the argument like a pointer to a C-string and it tries to print all the characters in that C-string until it gets to a NUL (0) byte. To get around this behaviour, you have to cast the addresses to void* like you are doing every other line.
You have just experienced the reason that arrays are sometimes considered second-class data types because they are treated specially in some situations (i.e. arrays of char are treated differently by some things but not others).
The Address of c: is empty because that's what you get when you try to print a string pointed to by &f.c. As dark_charlie pointed out, using an uninitialised variable is undefined behaviour, so technically anything can happen, but the former is probably the explanation for what you're seeing (though we can only guess).
The reason is that without the reinterpret cast &(f.c) is a char* pointer which is treated as a string by cout. Because you haven't filled the char with anything, you invoke an undefined behavior (i.e. it can print anything).