Accessing char member variable address of a structure - c++

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).

Related

c++ segfault and pointers confusion (I have the feeling I'm missing something terribly obvious)

I'm a python programmer new to C++. Currently getting a segfault when trying to play around with pointers. Can someone explain this behavior? I suspect there's something significant about cout that I'm not understanding.
#include<iostream>
using namespace std;
int main() {
int var; // declaration
cout << "var declared" << endl;
cout << "var : " << var << endl;
cout << "&var : " << &var << endl;
var = 10; // initialization
cout << "\nvar initialized" << endl;
cout << "var : " << var << endl;
cout << "&var : " << &var << endl;
int* ptr; // declaration
cout << "\nptr declared" << endl;
cout << "ptr : " << ptr << endl;
cout << "*ptr : " << *ptr << endl;
cout << "&ptr : " << &ptr << endl;
ptr = &var; // initialization
cout << "\nptr initialized : " << endl;
cout << "ptr : " << ptr << endl;
cout << "*ptr : " << *ptr << endl;
cout << "&ptr : " << &ptr << endl;
return 0;
}
using this compiler command
g++ --std=c++14 main.cpp -o main_exec;
This code produces the following output
var declared
var : 0
&var : 0x7fff55724478
var initialized
var : 10
&var : 0x7fff55724478
ptr declared
ptr : 0x0
[1] 82727 segmentation fault ./main_exec
This code obviously compiles but produces a segfault at runtime.
Things I've tried
I've tried combinations of commenting out the lines that include *ptr and the lines that include &ptr, short story is some combinations produce no segfault. It seems that I can use *ptr 1 time and not in combination with &ptr
You declared a pointer to an integer, but not initialized or assigned it with any pointer (i.e. to memory address of an integer variable).
int* ptr; // declaration
The line above says, ptr is a pointer (that would point to memory address of an integer variable). In your case it just says it is a pointer, what it does point is not defined.
When you hit this line,
cout << "*ptr : " << *ptr << endl;
Here *ptr means, get the value at address (the address that actually would store the value) and is being pointed by ptr. However ptr points to nothing. So you're trying to access memory in a way that is not permitted which leads to the segmentation fault.
Just remember that pointers are variable that as their values store memory address of another variable.
int *ptr; // would store memory address of an integer type variable.
int a = 5; // would store an integer variable.
ptr = &a; // Here &a gets the address of variable a and stores in *ptr
cout<<*ptr // Here *ptr gets the value of variable whose memory address is pointed to by *ptr.
Edit
To answer the question if int * ptr = new int; is valid.
Yes it will reserve you a memory location and allows you to later store values on that location later, as shown in code below,
int* ptr = new int; // gets memory address and assigns to *ptr
*ptr = 5; // assigns value 5 to the memory being pointed by *ptr
cout<<*ptr; // output 5
However you're supposed to not do this unless you've a particular need.
Variables reserve you memory, and give you a friendly variable name of your choice.
Anything you create with new is not deleted automatically, as suggested in comment section.
Variables, in contrast to this, are deleted automatically when they get out of scope (block, function, loop, etc.)

Confusing operation in c++ program while understanding move semantics

I am trying to grasp the concept of move semantics, rvalues, lvalues in c++ and am facing a problem. I am first looking at this popular answer - https://stackoverflow.com/a/3109981/9576161
I wrote a small program based on that reply to understand what is going on. I am using g++ (on linux) and the -fno-elide-constructors for compiling without rvalue optimization by the compiler.
Here is the small program:
#include <iostream>
#include <cstring>
using namespace std;
class string {
public:
char* data;
string (const char* p) {
cout << "Constructor 1 called\n";
size_t size = strlen(p) + 1;
data = new char[size];
cout << "this location is: " << this << endl;
memcpy (data,p,size);
}
string (string&& that) {
cout << "Constructor 2 called\n";
//cout << "data is " << data << " data location is: " << &data << endl;
cout << "data location is: " << &data << endl;
cout << "that.data is " << that.data << " that.data location is: " << &that.data << endl;
data = that.data;
that.data = nullptr;
cout << "this location is: " << this << " data is: " << data << endl;
cout << "data location is: " << &data << endl;
cout << "that.data location is: " << &that.data << endl;
}
~string() {
delete[] data;
cout << "Destructor called for object located at: " << this << endl;
}
void print() {
cout << "String is: " << data << endl;
}
};
int main () {
::string R = "12345";
cout << "R constructed and located at: " << &R << endl << endl;
return 0;
}
On running the program, I see the following result:
ubuntu#thinkpad:~/programming_practice/c_projects$ g++ -fno-elide-constructors move_semantics_short.cpp
ubuntu#thinkpad:~/programming_practice/c_projects$ ./a.out
Constructor 1 called
this location is: 0x7fffac01bb80
Constructor 2 called
data location is: 0x7fffac01bb78
that.data is 12345 that.data location is: 0x7fffac01bb80
this location is: 0x7fffac01bb78 data is: 12345
data location is: 0x7fffac01bb78
that.data location is: 0x7fffac01bb80
Destructor called for object located at: 0x7fffac01bb80
R constructed and located at: 0x7fffac01bb78
Destructor called for object located at: 0x7fffac01bb78
ubuntu#thinkpad:~/programming_practice/c_projects$
Notice the line data = that.data in the second constructor (where it says "Constructor 2 is called"). What does it do? Aren't data and that.data both character pointers? Why is data not changing in value? Shouldn't data now equal the value of that.data which is 0x7fffac01bb80? Instead it seems like some kind of memcopy is occurring and the character string that that.data points to is now pointed to by data. Any hints on what is going on would be helpful.
The type of &data is char**. That is, it's the memory location of the pointer that stores the memory location of some char.
data = that.data; does not make &data equal &that.data. It just makes data and that.data equal. They now point to the same char, but they each exist independently in memory.
If instead of printing data's address, you print the address stored in data, you can see that you are stealing the array of chars that was owned by that in your move constructor.

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

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

How to print value of a Variable using its memory address?

Suppose 0xfe2200 is the memory address of a variable var2 and I want to display the value stored in it, E.g
cout<< "Value stored in the given address is : " << 0xfe2200 << " ";
I tried following but all in vain
cout << "Value is : " << *0xfee2200 << " ;
cout << "Value is : " << &0xfee200 << " ;
Assuming the address points to int, you may do:
cout << "Value is : " << *reinterpret_cast<int*>(0xfee2200);
as literal 0xfee2200 is an interger type whereas you expected a pointer.
You have to decide as what type of data you want to interpret the memory content and cast it accordingly:
const char* tmp = "foofoo"; // Valid ptr for this example
const void* address = tmp; // Set to your address
const int* i = reinterpret_cast<const int*>(address);
const unsigned short* us = reinterpret_cast<const unsigned short*>(address);
const char* c = reinterpret_cast<const char*>(address);
std::cout << "i: " << (*i)
<< "\nus: " << (*us)
<< "\nc: " << (*c);
Output:
i: 1718579046
us: 28518
c: f

pointer to array c++

My understanding about assigning an array to a pointer is that the pointer is pointing at the first index of the array, so when printout the pointer, it should print out the address of the first index of the array, but how come in this case the cout printed out the value of the whole array? even though I explicitly indicated that I wanted the address of the first index
char foo[] = {'A','B','C','\0'};
char* p = foo;
char* q = &(foo[0]);
cout <<"from p: " << p << endl;
cout << "from q: " << q << " " << &(foo[0]) << endl;
//output
from p: ABC
from q: ABC ABC
the second question is that I see the difference between those two lines is that one is an array of pointer to char, the other is a pointer to a char array, is that correct? is the parenthesis necessary?
char* bar1[4];
char (*bar2)[4] = &foo;
cout << "address of foo is " << bar2 << endl;
//output
address of foo is 0x7fff192f88b0
The address of the foo array should be the same as the address of A, right? How do I printout the address of A? since I failed to do so. Thank you very much
<< has a dedicated overload for const char *, because that's what a C-style string is. Try this:
cout << static_cast<const void *>(bar2) << endl;