I was trying to access the private data members of the class. Everything was going fine until I came upon the int*. I don’t get what it is. I think it’s something that we can use to create a new memory address.
My code :
#include <iostream>
using namespace std;
class x
{
int a, b, c, d;
public:
x()
{
a = 100;
b = 200;
c = 300;
d = 400;
}
};
int main()
{
x ob;
int *y = (int *)&ob;
cout << *y << " " << y[1] << " " << y[2] << " " << y[3] << endl;
}
Can anyone help me in understanding it?
Its a c-style cast to access the memory occupied by the struct x as a set of ints.
It takes the address of ob, casts it from 'address of' (ie a pointer to) x into a pointer to int. The compiler happily assigns this cast to y, so you can manipulate it, or in this case, print out the memory blocks as ints. As the struct happens to be a group of ints anyway, it all works even though its a bit of a hack. I guess the original coder wanted to print out all 4 ints without having to specify each one in turn by variable name. Lazy.
Try using a cast to a char* (ie 1 byte at a time) and print those out. You'll be basically printing out the raw memory occupied by the struct.
A good C++ way would be to create an operator<< function that returns each variable formatted for output like this, then write cout << ob << endl; instead.
Related
int main()
{
int a = 2; // address is 0x7ffeefbff58c
int *b = &a;
std::cout << "address of a: " << b << std::endl;
return 0;
}
I have my int variable a at address 0x7ffeefbff58c, but can I directly assign int* b with 0x7ffeefbff58c?
I tried int * b = 0x7ffeefbff58c;
But there is an error says "cannot initialize a variable of type 'int *' with an rvalue of type 'long'", so do I have to use the address of a (&a) to initialize the pointer? or there is other way to do it?
can I directly assign int* b with 0x7ffeefbff58c?
Technically, yes.
If so, how to do that?
With reinterpret cast.
But do realise that there is absolutely no guarantee in general that a would be in the address 0x7ffeefbff58c. As such, there isn't much that you can do with such integer reinterpreted as a pointer. Doing this with a local variable would be pointless.
A case where interpreting integer as a pointer is useful is some embedded systems that reserve some constant memory addresses for special purposes.
Heere is an example:
#include <iostream>
int main()
{
int *b = (int*) 0x7ffeefbff58c;
std::cout << "b: " << b << std::endl;
return 0;
}
after compilation and execution you will see output:
b: 0x7ffeefbff58c
I can't seem to find the answer on here, but I'm sorry if this is a duplicate. Here's my question: When I have two pointers to the same location, then I change the address of one (let's say pointer A), will I (by accident) be changing the address of the other pointer (pointer B)? Or will pointer B's location stay the same?
Changing the contents of a pointer (as opposed to the object being pointed to) will not affect other pointers to the same object.
Picture speaks a thousand words.
Pointers are pointing to another memory place, at the same time, they have their own memory space.
Two pointers, A and B point to the same place, yet, they are kept in separate memory locations. (Left half of the image)
If you change B, you will only change what B is pointing, A remains the same. (Right half of the image)
Pointer B's location will stay the same.
Because pointer A and pointer B are different pointer,they have different memory address.That means they are independent each other although both of them point to the same memory address.
But you should be careful when you try to change pointer A's content,this operation may cause pointer B be a wild pointer by accident!
A pointer holds the memory address of a piece of data in memory.
The value of the pointer variable is this address.
int targetA = 1;
int targetB = 2;
int *pointerA = &targetA;
int *pointerB = &targetA;
printf("%p, %p\n", pointerA, pointerB);
// => 0x7fff5c78e8f8, 0x7fff5c78e8f8
pointerB = &targetB;
printf("%p, %p\n", pointerA, pointerB);
// => 0x7fff5c78e8f8, 0x7fff5c78e8f4
By assigning a different address / location to the pointer you just change what it points to, other variables are not affeted.
You can see the output of the below code :
#include <iostream>
int main(int argc, char **argv){
int a = 3, d = 4;
int *b = &a, *c = &a;
std::cout << b << ", " << c << std::endl;
b = &d;
std::cout << b << ", " << c << std::endl;
}
The following is the output of the code :
0x7ffca3788e40, 0x7ffca3788e40
0x7ffca3788e44, 0x7ffca3788e40
Clearly, changing the address b points to, has nothing to do with the address pointed by pointer c.
But you can have a near-similar phenomena when you use references. A reference is an entity that is an alias for another object. Suppose you have
int &ref = a;
ref = 5;
Now, changing the variable ref will also bring a change in the value of variable a, equating it to 5.
Let's take a look at this code snippet.
#include <iostream>
#include <string>
using namespace std;
int main ()
{
int * myp1, * myp2;
int myvalue;
myp1 = &myvalue;
myp2 = &myvalue;
myvalue = 10;
cout << "first address is " << myp1 << '\n';
cout << "second address is " << myp2 << '\n';
Here, the outputs are the same (when I run it, I get first address is 0x759ba27bb1d8
second address is 0x759ba27bb1d8).
int myvalue2;
myp1 = &myvalue2;
myvalue2 = 20;
cout << "first address is " << myp1 << '\n';
cout << "second address is " << myp2 << '\n';
return 0;
}
Here, the addresses are different, but myp2 points to the same address as above.
And it makes sense; you have two separate things pointing to the same address. Why would changing what one thing points to change the other?
A (possibly very bad analogy) would be: consider that you and someone on the other end of the world are pointing at the sky (say, at the same point in the sky). Then, you point at the ground. Just because you pointed at the ground, doesn't mean the other guy will stop pointing at the sky.
Hope that helps.
I found out that address of first element of structure is same as the address of structure. But dereferencing address of structure doesn't return me value of first data member. However dereferencing address of first data member does return it's value. eg. Address of structure=100, address of first element of structure is also 100. Now dereferencing should work in the same way on both.
Code:
#include <iostream>
#include <cstring>
struct things{
int good;
int bad;
};
int main()
{
things *ptr = new things;
ptr->bad = 3;
ptr->good = 7;
std::cout << *(&(ptr->good)) <<" " << &(ptr->good) << std::endl;
std::cout << "ptr also print same address = " << ptr << std::endl;
std::cout << "But *ptr does not print 7 and gives compile time error. Why ?" << *ptr << std::endl;
return 0;
}
*ptr returns to you an instance of type of things, for which there is no operator << defined, hence the compile-time error.
A struct is not the same as an array†. That is, it doesn't necessarily decay to a pointer to its first element. The compiler, in fact, is free to (and often does) insert padding in a struct so that it aligns to certain byte boundaries‡. So even if a struct could decay in the same way as an array (bad idea), simply printing it would not guarantee printing of the first element!
† I mean a C-Style array like int[]
‡ These boundaries are implementation-dependent and can often be controlled in some manner via preprocessor statements like pragma pack
Try any of these:
#include <iostream>
#include <cstring>
struct things{
int good;
int bad;
};
int main()
{
things *ptr = new things;
ptr->bad = 3;
ptr->good = 7;
std::cout << *(int*)ptr << std::endl;
std::cout << *reinterpret_cast<int*>(ptr) << std::endl;
int* p = reinterpret_cast<int*>(ptr);
std::cout << *p << std::endl;
return 0;
}
You can do a cast of the pointer to Struct, to a pointer to the first element of the struct so the compiler knows what size and alignment to use to collect the value from memory.
If you want a "clean" cast, you can consider converting it to "VOID pointer" first.
_ (Struct*) to (VOID*) to (FirstElem*) _
Also see:
Pointers in Stackoverflow
Hope it helps!!
I found out that address of first element of structure is same as the address of structure.
Wherever you found this out, it wasn't the c++ standard. It's an incorrect assumption in the general case.
There is nothing but misery and pain for you if you continue down this path.
I wrote a simple piece of C++ code to pass addresses by reference.
I am passing the address of a variable (say y) and an array (say arr) to a class. Both arr and y will get modified inside the class. I want to have the modified values in my main().
Please find my question in the below piece of code as it is easier that way. Thanks.
#include <iostream>
using namespace std;
class A
{
public:
// Assign values to the array and increment _x.
void increment()
{
(*_x)++;
(*_arr)[0] = 1; // Q1. Is it safe to directly access the array like this.
(*_arr)[1] = 2; // Don't I have to allocate memory to the array ?
(*_arr)[2] = 3;
}
// Get the address of the Variable that is passed in main. x will now have &y2.
A (int* &arr, int* &x):
_x(x)
{
*_arr = arr;
}
private:
int* _x;
int** _arr;
};
int main()
{
int y = 9;
int arr[5];
int *pY = &y;
int *pArr = arr;
A *obj1 = new A(pArr, pY);
// This gives a compile time error. warning: initialization of non-const reference int *&' from rvalue `int *'
// A *obj1 = new A(&y); <-- Q2. Why does this give a Compile Time Error ?
obj1->increment();
cout << "y : " << y << endl;
cout << "[0]: " << arr[0] << "; [1]: " << arr[1] << "; [2]: " << arr[2] << endl;
cout << endl;
return 0;
}
In A::increment() function, I am directly assigning values to the array without
allocating memory. Is it safe to do ? If not, how can I allocate memory so that
I can still get the modified array values in main() ?
Why do I get a compile time error whey I pass &y to A's constructor ?
Thanks in advance.
Question 1
In A::increment() function, I am directly assigning values to the array without allocating memory. Is it safe to do ? If not, how can I allocate memory so that I can still get the modified array values in main() ?
Answer
Yes, it is safe.
Question 2
Why do I get a compile time error whey I pass &y to A's constructor ?
Answer
&y is not an lvalue. Hence, it cannot be used where the argument type is int*&.
Problem in posted code
*_arr = arr;
That is a problem since _arr has not been initialized to point to a valid memory. Using *_arr when _arr has not been initialized causes undefined behavior. You can change the type of _arr to:
int* _arr;
and simplify your code a little bit.
class A
{
public:
// Assign values to the array and increment _x.
void increment()
{
(*_x)++;
_arr[0] = 1; // Q1. Is it safe to directly access the array like this.
_arr[1] = 2; // Don't I have to allocate memory to the array ?
_arr[2] = 3;
}
// Get the address of the Variable that is passed in main. x will now have &y2.
A (int* &arr, int* &x):
_x(x),
_arr(arr)
{
}
private:
int* _x;
int* _arr;
};
without changing anything in main.
This is very rarely what you want; a T** is generally an array of arrays or else a pointer value that you want to modify in the caller’s scope. However, neither seems to be what you’re doing here.
It is safe to modify *_arr[0] if and only if _arr has been initialized to a array of non-const arrays, and (*_arr)[0] if and only if it has been initialized as a pointer to a non-const array. Neither appears to be the case here, but if it is, you probably want to give the array length explicitly.
In this example, &y is a constant. You can’t modify it, so you can’t pass it as a non-const variable. You can declare a pointer int *py = &y; and pass that. But consider whether that’s what you want to do.
By the way, it’s not good style to use identifiers that start with underscores, because by the standard, they’re reserved for the compiler to use.
You should tell us what you are trying to do. In my opinion it's nonsense using raw pointers/arrays and naked new/(missing?) delete in C++ without good reason. I would also like to note that it is not considered good practice using the _prefix for class members. Usually leading _ are used for std implementations. I recommend using m_prefix if you insist on one. And why do you give _arr the type int**? Is is supposed to be a 2D-Array? Additionally, it doesn't really make sense passing a pointer by reference. A pointer is already a pointer, if you know what I mean, just pass the pointer around.
I'm just going to assume that you are doing this to understand manual memory management or pointer arithmetics or - wait, right: Tell us what you are trying to do and why. Nevertheless, I don't understand what you have the class for:
#include <iostream>
void increment(int& x, int *arr, int sz)
{
++x;
for (int i = 0; i != sz; ++i)
{
// this just numbers the values respectively (starting at 1)
arr[i] = i + 1;
}
}
int main()
{
using namespace std;
int y = 9;
const int sz = 5;
int arr[sz];
increment(y, arr, sz);
cout << "y : " << y << '\n'
<< "[0]: " << arr[0] << "; [1]: " << arr[1] << "; [2]: " << arr[2] << "\n\n";
}
To answer your questions:
2. First thing first: I don't see any constructor that only takes one argument.
Read up on "Undefined Behaviour (UB)" starting point: What are all the common undefined behaviours that a C++ programmer should know about?
I can't repeat enough that I don't understand what you are going for and that makes it hard to give solid advice.
I tried fixing your version.. well its still terrible... I highly recommend on reading up on std::array, std::vector. Maybe on pointers, C-Style Arrays and how to pass C-Style Arrays as function arguments (note: for regular C++ programming you wouldn't be doing/using that, usually).
#include <iostream>
class A {
public:
// Assign values to the array and increment m_x.
void increment()
{
++(*m_x);
m_arr[0] = 1;
m_arr[1] = 2;
m_arr[2] = 3;
}
A (int* arr, int* x):
m_x(x), m_arr(arr)
{
}
private:
int* m_x;
int* m_arr;
};
int main()
{
using namespace std;
int y = 9;
int arr[5];
A obj1(arr, &y);
obj1.increment();
cout << "y : " << y << '\n'
<< "[0]: " << arr[0] << "; [1]: " << arr[1] << "; [2]: " << arr[2] << "\n\n";
A obj2(arr, &y);
obj2.increment();
cout << "y : " << y << '\n'
<< "[0]: " << arr[0] << "; [1]: " << arr[1] << "; [2]: " << arr[2] << "\n\n";
}
You should also read up un pointers/references and their differences
I am actually trying to make your programming life easier. Sorry for long answer.
In answer to your first question
In A::increment() function, I am directly assigning values to the
array without allocating memory. Is it safe to do ? If not, how can I
allocate memory so that I can still get the modified array values in
main() ?
you allocated memory in main(), in the line
int arr[5];
In terms of class design, you defined your class constructor to accept reference arguments, which means that an existing int* must be passed to each argument:
A (int* &arr, int* &x)
and you do so when you invoke the constructor:
A *obj1 = new A(pArr, pY);
so in this program, what you are doing is safe. A potential danger if you expect to use this class in another context would be if your arr array in main() contained fewer than 3 elements, since your increment() function initializes the third element of the array.
In answer to your second question
Why do I get a compile time error whey I pass &y to A's constructor ?
In your original constructor,
// Get the address of the Variable that is passed in main. x will now have &y2.
A (int* &arr, int* &x):
_x(x)
{
*_arr = arr;
}
you are dereferencing _arr before it has been initialized. One way to solve this would be to do this:
// Get the address of the Variable that is passed in main. x will now have &y2.
A (int* &arr, int* &x):
_x(x)
{
_arr = new (int*);
*_arr = arr;
}
// Destructor
~A ()
{
delete _arr;
}
As an aside, you also use new in main(). Whenever you use new, you should also use delete to avoid a memory leak. So at the bottom of your program, before the return statement, add the following:
delete obj1;
still working at C++, but this came up in my book and I don't understand what it's for:
MyClass * FunctionTwo (MyClass *testClass) {
return 0;
}
My question is what is the signifigance of the first indirection operator
(MyClass *[<- this one] FunctionTwo(MyClass *testClass))?
I tried making a function like it in codeblocks, with and without the first * and I didn't see any difference in the way it ran or it's output:
int *testFunc(int *in) {
cout << in << endl;
cout << *in << endl;
return 0;
}
int testFuncTwo(int *in) {
cout << in << endl;
cout << *in << endl;
return 0;
}
I couldn't find anywhere that explained about it in my book.
Thanks,
Karl
The MyClass * means that this function returns a pointer to a MyClass instance.
Since the code is actually returning 0 (or NULL) this means that any caller to this function gets back a NULL pointer to a MyClass object.
I think the following are better examples:
int *testFunc(int *in) {
cout << "This is the pointer to in " << in << endl;
cout << "This is the value of in " << *in << endl;
return in;
}
int testFuncTwo(int *in) {
cout << "This is the pointer to in " << in << endl;
cout << "This is the value of in " << *in << endl;
return *in;
}
void test() {
int a = 1;
cout << "a = " << a;
int output = *testFunc(&a); // pass in the address of a
cout << "testFunc(a) returned " << output;
output = testFuncTwo(&a); // pass in the address of a
cout << "testFuncTwo(a) returned " << output;
}
Apologies, but I've not done C++ in years but the syntax may be a little off.
The general format for a function that takes a single value and returns a single value in C++ is:
return_type function name ( parameter_type parameter_name )
In your case, return_type is MyClass *, which means "pointer to MyClass"
In addition, in your case, parameter_type is also MyClass *.
In other words, your code could be rewritten as:
typedef MyClass *PointerToMyClass;
PointerToMyClass FunctionTwo (PointerToMyClass testClass)
{
return 0;
}
Does that look more familiar?
Given the nature of the question, I'm going to provide a somewhat crude answer.
A pointer points to something:
int x = 123; // x is a memory location (lvalue)
int* y = &x; // y points to x
int** z = &y; // z points to y
In the above code, z points to y which points to x which stores an integral, 123.
x->y->z[123] (this is not code, it's a
text diagram)
We can make y point to another integer if we want or NULL to make it point to nothing, and we can make z point to another pointer to an integer if we want or NULL to make it point to nothing.
So why do we need pointers which point to other things? Here's an example: let's say you have a simple game engine and you want to store a list of players in the game. Perhaps at some point in the game, a player can die by having a kill function called on that player:
void kill(Player* p);
We want to pass a pointer to the player, because we want to kill the original player. Had we done this instead:
void kill(Player p);
We would not kill the original player, but a copy of him. That wouldn't do anything to the original player.
Pointers can be assigned/initialized with a NULL value (either NULL or 0) which means that the pointer will not point to anything (or cease to point to anything if it was pointing to something before).
Later you will learn about references which are similar to pointers except a pointer can change what it points to during its lifetime. A reference cannot, and avoids the need to explicitly dereference the pointer to access the pointee (what it's pointing to).
Note: I kind of skirted around your original question, but the sample code you provided has no inherent meaningful behavior. To try to understand that example without first understanding pointers in a general sense is working backwards IMHO, and you'd be better to learn this general theory first.
If you had something like int * Function() this would return a pointer to an integer. MyClass * just means that the function is going to return a pointer to an object of type MyClass. In c++ user defined objects are treated as first-class-objects, so once you create your own objects they can be passed as a parameter, returned from a subroutine, or assigned into a variable just like the standard types.
In the code blocks you posted there will be no difference in the output to the console because the thing you have changed is the type that the function returns (which is not used), the contents of the functions are identical.
When you define:
int *testFunc(int *in)
You are defining a function which returns a pointer to an int variable.
int testFuncTwo(int *in)
Returns just an int variable.
Zero in this case is undergoing an implicit cast - the first function returns (int*) 0, the second just 0. You can see this implicit cast in action if you change the prototype of your example function from returning a MyClass* to just returning a MyClass - if there's no operator int method in MyClass, you'll get a nice error.