I was given instructions to show that a pointer variable can contain a pointer to a valid object, deleted object, null, or a random value. Set four pointer variables a,b,c, and d to show these possibilities. The the thing im not sure about are the pointer objects. Can someone explain what I need to do to show case these pointers. or if I did it right.
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
class Pointer
{
public:
Pointer()
{
int num = 2;
}
Pointer(int num)
{
this->numb = num;
}
void set(int num)
{
numb = num;
}
int Get()
{
return numb;
}
private:
int numb;
};
int main ()
{
Pointer point;
Pointer* a;
a = &point;
Pointer*b = new Pointer(10);
delete b;
int* c = NULL;
srand(unsigned(time(0)));
int randNum = rand()%100;
int *d;
d = &randNum;
cout <<"Pointer a: " << a << endl;
cout <<"Pointer b: " << b << endl;
cout <<"Pointer c: " << c << endl;
cout <<"Pointer d: " << *d << endl;
//(*a) = (*b);
return 0;
}
Not a complete answer, because this is homework, but here’s a hint: once you generate random bits (The C++ STL way to do this is with <random> and perhaps <chrono>), you can store them in a uintptr_t, an unsigned integer the same size as a pointer, and convert those bits to a pointer with reinterpret_cast<void*>(random_bits). The results are undefined behavior. Trying to dereference the pointer might crash the program, or it might appear to work and corrupt some other memory location, or it might do different things on different runs of the program, but nothing you do with it is guaranteed to work predictably. This is Very Bad.
If “random” really means arbitrary, for this assignment, you could just declare a pointer off the stack (that is, inside a function and not static) and not initialize it. Ask your instructor if you aren’t sure.
That’s a very common source of irreproducible bugs, and I would recommend you get into the habit now of always initializing your pointer variables when you declare them. Often, that lets you declare them int * const, which is good practice, but even if you need to wait to assign a real value to them, if you initialize your pointers to NULL or nullptr, you will always see immediately in the debugger that the value is uninitialized, and you will always crash the program if you try to use it uninitialized.
I would like to first point out what the word NULL means or nullptr, which is what you should be using in C++11. The null pointer just assigns the pointer to an inaccessible address or location in the memory. This allows for safer code, because the "dangling pointers" left over could be bad.
A header file and another cpp file to define the class
Class Something{
// Class implementation here
};
Now lets go to the main.cpp file
#include "The header you made.hpp" // (.h or .hpp)
int main(int argc, char *argv[]){
Something objOne;
Something *objPointer = &objOne;
// Do stuff with objPointer
// Like use your member functions
Something *objPointerTwo = &objOne;
// Now objPointerTwo points to the same object
// Lets try some runtime allocation of memory
Something *objHeap = new Something();
// Do something with the pointer
// Watch this
delete objHeap;
objHeap = nulltpr;
// Now what happens when you try to access methods again with objHeap
// Your program will display a segmentation fault error
// Which means you are trying to mess with memory
// that the compiler does not want you too
}
All right so what is this memory? Well to put it simply you have the heap and the stack. All the stuff you put into your program is put into the stack when it is compiled. So when the program runs the code follows main and traces the stack kind of like a stack of boxes. You may get need to search through all the top ones to get to the bottom. Now what if a person didn't know for example how many students were going to be in the class that year. Well the program is already running how do you make more room? This is where the heap comes in. The new keyword allows you to allocate memory at runtime, and you can "point" to memory on the "heap" if you will. Now while this is all good and cool, it can be potentially dangerous which is why people consider C++ and C dangerous languages. When you are done using that memory on the heap you have to "delete" it so when the pointer moves, the memory does not get lost and cause problems. It is kind of like a sneaky ninja and it goes and causes trouble.
A good way to think about how pointers can be good for objects is if you create say a deck class, well how many cards does the user want we wont know until runtime, so lets have them type in the number, and we can allocate it on the heap! Look Below
int main(void){
int count;
Deck *deck = nullptr;
std::cout << "Enter amount of cards please:";
std::cin >> count;
deck = new Deck(count); // RUNTIME ALLOCATION ON HEAP!!!!
// This is so cool right, you can have a deck of any size
// Do stuff with deck
// Now that we are done with the deck don't forget to delete it
// We do not need all those cards on the heap anymore so....
delete deck; // Ahhh almost done
deck = nullptr; // Just in case since dangling pointers are weird
}
The key thing to understand here is, what is a pointer, what is it pointing to, and how do they work with the memory!
Related
Consider the code below. Here I try to create an array that is suppost to take in pointers to objects of type Person. I wanted it's size to be 3 so i put a 3 inside the [ ]. However this 3 seem to do nothing. So i'm wondering what is the correct way of declaring the array? As you can see from the line below i can put the address to a person in 23 position of the array. Which I think is a bit weird since the memory is not reserved.
#include <iostream>
class Person {
//some code
};
int main() {
Person person1;
Person* array_of_person[3];
array_of_person[22] = &person1;
for (int i = 0; i < 10; i++) {
std::cout << array_of_person[i] << "hey im out of bounds " << std::endl;
}
}
However this 3 seem to do nothing.
The 3 means: You declared an array of size 3.
The rest of your code is undefined behaviour for accessing this array out-of-bounds. I presume you expected to get some error or something. This is not how C++ works. If you do something wrong, wrong things will happen. When your code has undefined behaviour the compiler is not mandated to issue an error. As the name suggests it is undefined what your code does.
If you want some feedback use a vector and its at method, as in:
#include <iostream>
class Person {
//some code
};
int main() {
Person person1;
std::vector<Person> array_of_person(3);
array_of_person.at(22) = person1; // out-of-bounds exception
for (int i = 0; i < 10; i++) {
std::cout << array_of_person.at(i) << "hey im out of bounds " << std::endl;
// more out-of-bounds exceptions starting from index 3
}
}
Its not clear why you used pointers, dont do it when not necessary.
The array is declared correctly.
Out of bounds access is not always detected by C++, especially if there is nothing else after the array. If you had some other variables declared after it, they probably would be trashed. Memory is allocated by pages, which typically are 4096 bytes.
C++ doesn't do runtime checking on array bounds. That's up to you. (And it's also why there are array classes in the standard library.)
So you're free to stuff something into array_of_persons[22], but you're stepping on random memory somewhere. You have no idea what you stepped on, but nothing is going to stop you.
But you changed the value of some random data.
Sure, the memory is not reserved, but it still exists. Those c style arrays don't have bound checks (like python or other languages).
You need to be carefulle what you access.
Arrays are like pointers in C++.
array_of_person[22] is the same as *(array_of_person+22)
Its the pointer to the 0th value of array_of_person[] and skips 22 elements ahead.
EDIT:
As mentioned in the comments: the memory is not guaranteed to exist or what data there is. You are most likely either gonna segfault or corrupt some data. C++ doesn't guarantee anything here except for which Address you are trying to access.
I have two structures
struct temp
{
char name[20];
};
struct abc
{
temp *ptr;
int num;
};
Here is the main function.
main()
{
abc *rptr;
strcpy((rptr->ptr)->name,"Wellcome");
cout<<(rptr->ptr)->name; //works
cout<<*((*rptr).ptr).name; //does not work why?
}
I would like to know why the last cout does not work.
The line:
cout << *((*rptr).ptr).name;
Doesn't work because the action . on ((*rptr).ptr) has higher precedence than the *
Fix it using:
cout << (*((*rptr).ptr)).name;
Important
Please note that your code has a bigger issues in it:
You are writing to an uninitialized pointer rptr
Your struct abc contains a pointer to temp, not an instance!
Doing this: strcpy((rptr->ptr)->name,"Wellcome"); is considered a crime! You are corrupting all of your memory!
Instead, it should look like this:
abc *rptr = new abc();
rptr->ptr = new temp();
strncpy(rptr->ptr->name, "Wellcome", sizeof(rptr->ptr->name));
cout << rptr->ptr->name << endl;
delete rptr->ptr;
delete rptr;
Fixes:
Allocate rptr object
Allocate ptr object inside your rptr
Copy the "Wellcome" string carefully (Add bounds checking)
It doesn't work because of precedence rules. . (structure member selection) has a higher binding than * (pointer dereference). Put in some parenthesis and it'd work just fine. Notice how you put parenthesis around the inner pointer dereference, why did you skip the outer?
So the answer you accepted was an excellent answer that told you how to fix what you were doing and why it wasn't working.
This answer is to tell you what you should be doing instead. Because what you are doing is not really C++. In modern C++ it should be uncommon that you ever have to deal with pointers. And this is a huge advantage that C++ has over C, and one of the chief reasons to choose the language in my opinion.
Here's how your two structures should look:
#include <memory>
#include <string>
struct temp
{
::std::string name;
};
struct abc
{
::std::unique_ptr<temp> ptr;
int num;
};
And here's how your main should've looked:
#include <iostream>
#include <memory> // Probably redundant, but you do use it directly here.
int main()
{
using ::std::unique_ptr;
using ::std::cout;
using ::std::make_unique;
// If you don't have make_unique (it was added in C++14) use new instead.
unique_ptr<abc> rptr = make_unique<abc>();
rptr->ptr = make_unique<temp>();
rptr->ptr->name = "Wellcome";
cout << (rptr->ptr)->name;
cout << (*(*rptr).ptr).name;
return 0;
}
The unique_ptr objects will automatically free the things they're pointing at when they go out of scope. So, first rptr goes away and so the abc it points to is destroyed, and this will destroy the ptr member of abc which will result in the temp you allocated also being freed.
Yes, those are technically pointers, but the compiler will manage their lifetime for you so that you don't have leaks or accidentally free something twice.
Also, using ::std::string means you don't have to worry about unsafe operations like strcpy and strlen at all. It will just work.
Now, presumably your program was just an example, and you have a larger program that you're actually working on. But these principles are the same. Do not use bare pointers unless you absolutely have to. Use the C++ pointer classes. They are your friends and will make life much easier for you. Use ::std::string, ::std::vector, ::std::array, and other similar classes from the standard library. They will make your life a lot easier.
How variable int a is in existence without object creation? It is not of static type also.
#include <iostream>
using namespace std;
class Data
{
public:
int a;
void print() { cout << "a is " << a << endl; }
};
int main()
{
Data *cp;
int Data::*ptr = &Data::a;
cp->*ptr = 5;
cp->print();
}
Your code shows some undefined behavior, let's go through it:
Data *cp;
Creates a pointer on the stack, though, does not initialize it. On it's own not a problem, though, it should be initialized at some point. Right now, it can contain 0x0badc0de for all we know.
int Data::*ptr=&Data::a;
Nothing wrong with this, it simply creates a pointer to a member.
cp->*ptr=5;
Very dangerous code, you are now using cp without it being initialized. In the best case, this crashes your program. You are now assigning 5 to the memory pointed to by cp. As this was not initialized, you are writing somewhere in the memory space. This can include in the best case: memory you don't own, memory without write access. In both cases, your program can crash. In the worst case, this actually writes to memory that you do own, resulting in corruption of data.
cp->print();
Less dangerous, still undefined, so will read the memory. If you reach this statement, the memory is most likely allocated to your program and this will print 5.
It becomes worse
This program might actually just work, you might be able to execute it because your compiler has optimized it. It noticed you did a write, followed by a read, after which the memory is ignored. So, it could actually optimize your program to: cout << "a is "<< 5 <<endl;, which is totally defined.
So if this actually, for some unknown reason, would work, you have a bug in your program which in time will corrupt or crash your program.
Please write the following instead:
int main()
{
int stackStorage = 0;
Data *cp = &stackStorage;
int Data::*ptr=&Data::a;
cp->*ptr=5;
cp->print();
}
I'd like to add a bit more on the types used in this example.
int Data::*ptr=&Data::a;
For me, ptr is a pointer to int member of Data. Data::a is not an instance, so the address operator returns the offset of a in Data, typically 0.
cp->*ptr=5;
This dereferences cp, a pointer to Data, and applies the offset stored in ptr, namely 0, i.e., a;
So the two lines
int Data::*ptr=&Data::a;
cp->*ptr=5;
are just an obfuscated way of writing
cp->a = 5;
I am learning C++ from a game development standpoint coming from long time development in C# not related to gaming, but am having a fairly difficult time grasping the concept/use of pointers and de-referencing. I have read the two chapters in my current classes textbook literally 3 times and even googled some different pages relating to them, but it doesn't seem to be coming together all that well.
I think I get this part:
#include <iostream>
int main()
{
int myValue = 5;
int* myPointer = nullptr;
std::cout << "My value: " << myValue << std::endl; // Returns value of 5.
std::cout << "My Pointer: " << &myValue << std::endl; // Returns some hex address.
myPointer = &myValue; // This would set it to the address of memory.
*myPointer = 10; // Essentially sets myValue to 10.
std::cout << "My value: " << myValue << std::endl; // Returns value of 10.
std::cout << "My Pointer: " << &myValue << std::endl; // Returns same hex address.
}
I think what I'm not getting is, why? Why not just say myValue = 5, then myValue = 10? What is the purpose in going through the added layer for another variable or pointer? Any helpful input, real life uses or links to some reading that would help make sense of this would be GREATLY appreciated!
The purpose of pointers is something you will not fully realize until you actually need them for the first time. The example you provide is a situation where pointers are not needed, but can be used. It is really just to show how they work. A pointer is a way to remember where memory is without having to copy around everything it points to. Read this tutorial because it may give you a different view than the class book does:
http://www.cplusplus.com/doc/tutorial/pointers/
Example: If you have an array of game entities defined like this:
std::vector<Entity*> entities;
And you have a Camera class that can "track" a particular Entity:
class Camera
{
private:
Entity *mTarget; //Entity to track
public:
void setTarget(Entity *target) { mTarget = target; }
}
In this case, the only way for a Camera to refer to an Entity is by the use of pointers.
entities.push_back(new Entity());
Camera camera;
camera.setTarget(entities.front());
Now whenever the position of the Entity changes in your game world, the Camera will automatically have access to the latest position when it renders to the screen. If you had instead not used a pointer to the Entity and passed a copy, you would have an outdated position to render the Camera.
TL;DR: pointers are useful when multiple places need access to the same information
In your example they aren't doing much, like you said it's just showing how they can be used. One thing pointers are used for is to connect nodes like in a tree. If you have a node structure like so...
struct myNode
{
myNode *next;
int someData;
};
You can create several nodes and link each one to the previous myNode's next member. You can do this without pointers, but the neat thing with pointers is because they are all linked together, when you pass around the myNode list you only need to pass the first (root) node.
The cool thing about pointers is that if two pointers are referencing the same memory address, any changes to the memory address are recognized by everything referencing that memory address. So if you did:
int a = 5; // set a to 5
int *b = &a; // tell b to point to a
int *c = b; // tell c to point to b (which points to a)
*b = 3; // set the value at 'a' to 3
cout << c << endl; // this would print '3' because c points to the same place as b
This has some practical uses. Consider you have a list of nodes linked together. The data in each node defines some sort of task that needs to be done that will be handled by some function. As new tasks are added to the list, they get appended to the end. Since the function has a pointer to the node list, as tasks are added on it receives those as well. On the other hand, the function can also remove tasks as it completes them, which are then reflected back across any other pointers that are looking at the node list.
Pointers are also used for dynamic memory. Say you want the user to enter in a series of numbers, and they tell you how many numbers they want to use. You could define an array of 100 elements to allow for up to 100 numbers, or you could use dynamic memory.
int count = 0;
cout << "How many numbers do you want?\n> ";
cin >> count;
// Create a dynamic array with size 'count'
int *myArray = new int[count];
for(int i = 0; i < count; i++)
{
// Ask for numbers here
}
// Make sure to delete it afterwars
delete[] myArray;
If you pass an int by value, you will not be able to change the callers value. But if you pass a pointer to the int, you can change it. This is how C changed parameters. C++ can pass values by reference so this is less useful.
f(int i)
{
i= 10;
std::cout << "f value: " << i << std::endl;
}
f2(int *pi)
{
*pi = 10;
std::cout << "f2 value: " << pi << std::endl;
}
main()
{
i = 5
f(i)
std::cout << "main f value: " << i << std::endl;
f2(&i)
std::cout << "main f2 value: " << i << std::endl;
}
in main the first print should still be 5. The second one should be 10.
What is the purpose in going through the added layer for another variable or pointer?
There isn't one. It's a deliberately contrived example to show you how the mechanism works.
In reality, objects are often stored, or accessed from distant parts of your codebase, or allocated dynamically, or otherwise cannot be scope-bound. In any of these scenarios you may find yourself in need of indirectly referring to objects, and this is achieved using pointers and/or references (depending on your need).
For example some objects have no name. It can be an allocated memory or an address returned from a function or it can be an iterator.
In your simple example of course there is no need to declare the pointer. However in many cases as for example when you deal with C string functions you need to use pointers. A simple example
char s[] = "It is pointer?";
if ( char *p = std::strchr( s, '?' ) ) *p = '!';
We use pointers mainly when we need to allocate memory dynamically. For example,To implement some data structures like Linked lists,Trees etc.
From C# point of view pointer is quite same as Object reference in C# - it is just an address in memory there actual data is stored, and by dereferencing it you can manipulate with this data.
First of non-pointer data like int in your example is allocated on the stack. This means that then it goes out of the scope it's used memory will be set free. On the other hand data allocated with operator new will be placed in heap (just like then you create any Object in C#) resulting that this data will not be set free that you loose it's pointer. So using data in heap memory makes you do one of the following:
use garbage collector to remove data later (as done in C#)
manually free memory then you don't need it anymore (in C++ way
with operator delete).
Why is it needed?
There are basically three use-cases:
stack memory is fast but limited, so if you need to store big
amount of data you have to use heap
copying big data around is
expensive. Then you pass simple value between functions on the stack
it does copying. Then you pass pointer the only thing copied is just
it's address (just like in C#).
some objects in C++ might be
non-copyable, like threads for example, due to their nature.
Take the example where you have a pointer to a class.
struct A
{
int thing;
double other;
A() {
thing = 4;
other = 7.2;
}
};
Let's say we have a method which takes an 'A':
void otherMethod()
{
int num = 12;
A mine;
doMethod(num, mine);
std::cout << "doobie " << mine.thing;
}
void doMethod(int num, A foo)
{
for(int i = 0; i < num; ++i)
std::cout << "blargh " << foo.other;
foo.thing--;
}
When the doMethod is called, the A object is passed by value. This means a NEW A object is created (as a copy). The foo.thing-- line won't modify the mine object at all as they're two separate objects.
What you need to do is to pass in a pointer to the original object. When you pass in a pointer, then the foo.thing-- will modify the original object instead of creating a copy of the old object into a new one.
Pointers (or references) are vital for the use of dynamic polymorphism in C++. They are how you use a class hierarchy.
Shape * myShape = new Circle();
myShape->Draw(); // this draws a circle
// in fact there is likely no implementation for Shape::Draw
Attempts to use a derived class through a value (instead of pointer or reference) to a base class will often result in slicing and losing the derived data portion of the object.
It makes a lot more sense when you're passing the pointer to a function, see this example:
void setNumber(int *number, int value) {
*number = value;
}
int aNumber = 5;
setNumber(&aNumber, 10);
// aNumber is now 10
What we're doing here is setting the value of *number, this would not be possible without the use of pointers.
If you defined it like this instead:
void setNumber(int number, int value) {
number = value;
}
int aNumber = 5;
setNumber(aNumber, 10);
// aNumber is still 5 since you're only copying its value
It also gives better performance and you're not wasting as much memory when you're passing a reference to a larger object (such as a class) to a function, instead of passing the whole object.
Well to use pointers in programming is a pretty concept. And for dynamically allocating the memory it is essentiall to use pointers to store the adress of the first location of the memory which we have reserved and same is the case for releasing the memory, we need pointers. It's true as some one said in above answer that u cannot understand the use of poinetrs until u need it. One example is that u can make a variable size array using pointers and dynamic memoru allocation. And one thing important is that using pointers we can change the actual value of the location becaues we are accessing the location indirectly. More ever, when we need to pass our value by refernce there are times when references do not work so we need pointers.
And the code u have written is using dereference operator. As i have said that we access the loaction of memory indirectly by using pointers so it changes the actuall value of the location like reference objects that is why it is printing 10.
I thought I was fairly good with C++, it turns out that I'm not. A previous question I asked: C++ const lvalue references had the following code in one of the answers:
#include <iostream>
using namespace std;
int& GenX(bool reset)
{
static int* x = new int;
*x = 100;
if (reset)
{
delete x;
x = new int;
*x = 200;
}
return *x;
}
class YStore
{
public:
YStore(int& x);
int& getX() { return my_x; }
private:
int& my_x;
};
YStore::YStore(int& x)
: my_x(x)
{
}
int main()
{
YStore Y(GenX(false));
cout << "X: " << Y.getX() << endl;
GenX(true); // side-effect in Y
cout << "X: " << Y.getX() << endl;
return 0;
}
The above code outputs X: 100, X:200. I do not understand why.
I played with it a bit, and added some more output, namely, a cout before the delete x; and a cout after the new x; within the reset control block.
What I got was:
before delete: 0x92ee018
after new: 0x92ee018
So, I figured that static was silently failing the update to x, and the second getX was playing with (after the delete) uninitialized memory; To test this, I added a x = 0; after the delete, before the new, and another cout to ensure that x was indeed reset to 0. It was.
So, what is going on here? How come the new returns the exact same block of memory that the previous delete supposedly free'd? Is this just because that's what the OS's memory manager decided to do, or is there something special about static that I'm missing?
Thank you!
That's just what the memory manager decided to do. If you think about it, it makes a lot of sense: You just freed an int, then you ask for an int again... why shouldn't the memory manager give you back the int you just freed?
More technically, what is probably happening when you delete is that the memory manager is appending the memory block you freed to the beginning of the free list. Then when you call new, the memory manager goes scanning through its free list and finds a suitably sized block at the very first entry.
For more information about dynamic memory allocation, see "Inside storage allocation".
To your first question:
X: 100, X:200. I do not understand why.
Since Y.my_x is just a reference to the static *x in GenX, this is exactly how it supposed it to be - both are referencing to the same address in memory, and when you change the content of *x, you get a side effect.
You are accessing the memory block that is deallocated. By the c++ standard, that is an undefined behaviour, therefore anything can happen.
EDIT
I guess I have to draw :
You allocate the memory for an int, and you pass the object allocated on the heap to the constructor of Y, which stores that in the reference
then you deallocate that memory, but your object Y still holds the reference to the deallocated object
then you access the Y object again, which holds an invalid reference, referencing deallocated object, and the result you got is the result of an undefined behaviour.
EDIT2
The answer to why : implementation defined. The compiler can create new object at any location it likes.
i test your code in VC2008, the output is X: 100, X: -17221323. I think the reason is that the static x is freed. i think my test is reasonable.
This makes perfect sense for the code.
Remember that it is your pointer that is static, so when you enter this function a second time you do not need to make a new pointer, but ever time you enter this function you are making a new int for the pointer to point to.
You are also probably in debug mode where a bit more time is spent giving you nice addresses.
Exactly why the int that your pointer points to is in the same space is probably just down to pure luck, that and you are not declaring any other variables before it so the same space in memory is still free