How vector allocate memory - c++

Hii
I know that vector allocated contiguous fixed memory when it needs to push_back some items.And if its not able to fit into it it will alllocate new memory and copy old values into it and delete the old memory.
If that is the case how the following code works
#include<iostream>
#include<vector>
using namespace std;
class Test
{
public :
int val;
Test()
{
val=0;
}
};
int main()
{
vector<Test>vec;
Test t[10];
for (int i=0;i<5;i++)
vec.push_back(t[i]);
cout<<vec.capacity()<<endl; //printing 8
Test* obj=&vec[2];
obj->val=2;
cout<<obj<<endl;
for (int i=0;i<5;i++) //Adding 5 elements more
vec.push_back(t[i]);
Test* obk=&vec[2];
cout<<obk->val<<endl;
cout<<obj->val<<endl;
cout<<obj<<endl;
cout<<obk<<endl;
}
Here if you see obj is taking pointer of vec[2] which value in my machine is coming 0x8bcb048 .Then I am inserting 5 more items so vector will allocate new memory.Now if i am taking obk from vector[2] its coming different address 0x8bcb070 . But if i try to acess i with the help of obj its not giving any problem.Any reason ?

But if i try to access it with the help of obj its not giving any problem. Any reason?
This is undefined behavior - the fact that it appears to work is simply due to luck (whether good or bad luck is matter of opinion).
Essentially you're dereferencing a 'dangling' pointer. and just like if you dereference a pointer to a block of memory that's been freed, you simply read out old, stale data that happens to look like it has reasonable values. or you might read out something that appears to be garbage. Or you might cause a segfault.
One thing is for certain - it's a bug, whether it seems to act like one or not.

vectors are dynamic arrays. You are right when they overflow they are reallocated someplace else and all earlier initialized pointers/ iterators( which generally for vectors are also implemented as pointers, although the standards don't require it)/ address references become invalid. and earlier held memory space is freed finally.
Here is how events occur in simplistic terms:
currently available space is insufficient.
new memory space is acquired ( k times(generally k=2) as large as original memory size)
current array is copied to new memory locations
old = current; current = new; { this ensures atomicity for single insertions}
old memory is freed.
Notice that old memory location's data is not destroyed or reset. So when the resources are needed again that might or might not be reused. But the original memory location that you have is a false location and must be avoid always.

When a vector reallocates, all iterators, pointers and references that you obtained prior to the reallocation are invalidated. Using them leads to undefined behavior, which includes "apparently not giving any problems".
To visualize the problem, you can insert debug outputs in the constructors and the destructor. You could also log which objects exist at any point in time:
class Test;
std::set<Test*> valid_Test_objects;
class Test
{
int val;
public:
Test() : val(0)
{
valid_Test_objects.insert(this);
std::cout << "constructed Test object # " << this << std::endl;
}
Test(const Test& that) : val(that.val)
{
std::cout << "constructed Test object # " << this << std::endl;
valid_Test_objects.insert(this);
}
~Test()
{
std::cout << "destructing Test object # " << this << std::endl;
valid_Test_objects.erase(this);
}
int value()
{
std::cout << " accessing Test object # " << this << std::endl;
if (valid_Test_objects.find(this) == valid_Test_objects.end())
{
abort();
}
return val;
}
};
int main()
{
std::vector<Test> vec;
vec.reserve(3);
Test x;
vec.push_back(x);
Test* p = &vec[0];
std::cout << p->value() << std::endl;
std::vector<Test>::size_type cap = vec.capacity();
while (cap == vec.capacity()) vec.push_back(x);
std::cout << p->value() << std::endl;
}
Unfortunately, we should not even try to call p->value() when p is invalid. Enjoy your stay at undefined behavior land ;-)

If you're asking why there's no crash when you try to access 'obj' then I would say you should try to run it in Release mode and see. In any case, obj should not be accessible, as the pointer that was returned by &vec[2] was invalidated when the vector increased its capacity. It could still be pointing to some random junk that happens to be allocated to your processes.

Related

c++ understanding accessing global variables after cleanup does not give some sort of error

I have a question about how global variables work in c++.
I know global variables are evil so that is not the point of this question. I just want a deeper understanding of what is happening in the following example.
#include <cstdint>
#include <iostream>
#include <vector>
class B
{
public:
B();
~B();
private:
static std::vector<int32_t> v_;
};
B::B()
{
std::cout << "v_.size() = " << v_.size() << std::endl;
for (auto i : v_)
std::cout << i << std::endl;
}
B::~B()
{
std::cout << "v_.size() = " << v_.size() << std::endl;
std::cout << "v_[0] = " << v_[0] << std::endl;
std::cout << "v_.at(0) = " << v_.at(0) << std::endl;
for (auto i : v_)
std::cout << i << std::endl;
}
B b;
std::vector<int32_t> B::v_ { 5, -7 };
int main()
{
return 0;
}
Gives this output:
$ ./test
v_.size() = 0
v_.size() = 2
v_[0] = 0
v_.at(0) = 0
0
0
Why is the size of the vector in the destructor of B still 2?
When I access the elements of the vector I get random memory, which I sort of understand because the vector gets cleaned up before B. But to me the size of the vector should be 0 or even way better throw some sort of error when asking for the size. Even when using at() function It doesn't throw an error because the size is still 2.
I also know I can fix this by switching the initialization of b and the vector. My question is more why this specific example doesn't throw some sort of error, cause in my opinion it should.
Note: like my comment: why does this behavior fall under undefined behavior instead of reading or writing an illegal memory location since the vector doesn't exist at that point? I was kinda thinking this would/should generate a seg fault and I don't understand why it doesn't
Undefined behavior means that the behavior of your program is not defined by the C++ standard. A conforming C++ compiler can do anything with a program that has, or will, exhibit undefined behavior (yes, UB can time travel).
Your program exhibits undefined behavior by accessing v_ as an object prior to it being constructed in B::B. Given that it does this, nothing about your programs execution is specified or constrained by the C++ standard.
In this case, the compiler treats the UB access as if it was accessing an empty std::vector. This is valid, because anything is valid. The program then proceeds as-if you hadn't done the UB (other than the above symptom), which is also a valid option.
If we imagine removing the UB in the ctor, during destruction your program again exhibits UB. This time by accessing v_ as a vector object after it was destroyed. Again, by doing this the behavior of your program is not defined or constrained by the C++ standard, before, at, and after the UB.
In this case, it behaves as if you have a vector of 2 values whose values are 0. That is conforming, because anything is conforming.
One of many possibilities is that the data was recycled on the heap, but the pointers where left dangling. Treating the vector's "rotted" data as pointers they still point 2 sizeof(int) apart, and .size() reads that as 2. The data pointed to, however, has been recycled on the heap, and there is different data there.

C++ init multiple class object inside for loop gives the same memory address?

My code snippet is as follows, however when I have 2 self defined classes and I define them, and print their memory address:
for(int i=0;i<2;i++){
Engine b;
Strategy d;
std::cout<<"be:"<<&b<<std::endl;
std::cout<<"elm:"<<&d<<std::endl;
}
it outputs:
be:0x7ffd92aee2c0
elm:0x7ffd92aede70
be:0x7ffd92aee2c0
elm:0x7ffd92aede70
i was expecting 2 different sets of memory addresses, but they are the same. Can someone tell me how to init into different address?
i was expecting 2 different sets of memory address
There is no reason to expect that. By the time the next iteration begins, the lifetime of the automatic object in the previous iteration has ended and so the object in the next iteration can reuse the same storage i.e. it can have the same memory address.
Can someone tell me how to init into different address?
You cannot specify the memory location where an object of automatic storage duration is allocated. But, if you create two objects whose lifetime overlaps, then they must necessarily be stored in separate addresses. john has shown how to do that using an array in his answer.
The obvious way is
Engine b[2];
Strategy d[2];
for(int i=0;i<2;i++){
std::cout<<"be:"<<&b[i]<<std::endl;
std::cout<<"elm:"<<&d[i]<<std::endl;
}
but the real question is why you care that the addresses are the same. Most likely its not something you need to worry about.
Both of the variables that you have outputted should only have 1 unique memory address, be, which is equal to
0x7ffd92aee2c0
was outputted twice, with no change to it whatsoever.
Then
elm:0x7ffd92aede70
was the same scenario, you outputted it twice with no change, what difference did you expect?
The code is working perfectly fine!
Objects created within block scope are created each time the block is entered and destroyed each time the block is left. In case of a loop, your objects b and d will be created and destroyed with each begin and end of an iteration, respectively. So you will get "new" objects with each iteration, but the compiler is free to use any address (even the ones used for the object of the prior iteration), so it may happen that you see the same addresses again and again. But it might also happen that you get different ones. Anyway, it makes no sense to rely on memory addresses of object which's life time has ended / will end, so the more interesting question is: "why do you care about memory addresses of e and d at all?".
To bring some light into that what happens try the following code. It shows how objects are created and destroyed in the course of your program:
class TestClass {
public:
TestClass (int x=0) : x (x) { cout << "Constructing " << x << endl; };
TestClass (const TestClass& t) : x (t.x) { cout << "CopyConstructing " << x << endl; };
TestClass (const TestClass&& t) : x (t.x) { cout << "Moving " << x << endl; };
~TestClass () { cout << "Destructing " << x << endl; };
int x;
};
int main() {
for(int i=0;i<2;i++){
TestClass b(i);
std::cout<<"elm:"<<&b<<std::endl;
}
}
Output:
Constructing 0
elm:0x7fff5fbff780
Destructing 0
Constructing 1
elm:0x7fff5fbff780
Destructing 1

returning pointer from function giving me random numbers

I am working on a small console game on my free time and have come across a bug I can't seem to fix no matter what I try. I have tried a lot of different things with the pointers so this is just the latest version of my code. I have been searching around and a few questions other's have asked indicated I may be experiencing a memory leak, or that I am reading values from beyond my arrays (don't understand how). However, those questions have been solved without leaving me any hints as to what is wrong with my code.
Basically, I have a function called int * spendAttribute(int point);
Since anything created in that function is out of scope in my main() I want to take 6 int out of that function, and bring them into my main().
I thought "hey why not use a pointer!" The function is supposed to return a pointer to an array created during the function, and paste it to another pointer created in main(), this has worked once before in my main(), but now it's not working and I have no clue why.
int * spendAttribute(int point)
{
string choice;
int hp,hpT,endur,endurT,dmg,dmgT,armor,armorT,agility,agilityT,evade,evadeT;
while(condition)
{
//do a bunch of junk ....
}
int stats[6] = {hp,endur,dmg,armor,agility,evade};
//some cout testing to see if values are correct (they are)
int* p_stats = new int [6]; //create a block of 6
p_stats = &stats[0]; //point to the first value of stats array
return p_stats; //return pointer
delete [] p_stats; //delete blocks
}
Note: I have tried without deleting the blocks and it still does not work. I tried this since I read that it might be a memory leak.I have tried it without using new at all.
main()
{
//.... some junk
while(main game loop)
{
int * pointer;
cout << "*************** Enter 'begin' to commence ****************** " << endl ;
cout << "*************** Enter 'spend' to use new attribute points ** " << endl ;
cin >> beginChoice; //declared before while loop
if(beginChoice == "spend")
{
cout << "total attributes: " << Bryan.returnAttribute() << endl ;
pointer = spendAttribute(Bryan.returnAttribute()); //copy pointer
cout << "TEST: " << endl ;
cout << pointer[0] << endl ; //out put is a bunch of random numbers..
cout << pointer[1] << endl ;
cout << pointer[2] << endl ;
cout << pointer[3] << endl ;
cout << pointer[4] << endl ;
cout << pointer[5] << endl ; //SOME DAMN BUG HERE
Bryan.addMaxHp(pointer[0]);
Bryan.addEndurance(pointer[0]);
Bryan.addDmg(pointer[0]);
Bryan.addArmor(pointer[0]);
Bryan.addAgility(pointer[0]);
Bryan.addEvasion(pointer[0]);
//after this character ends up having some ridiculous stats like -564553535%
//evasion or 9879967856 armor...
}
}
}
This method of transferring the array over to main worked for me before in this exact file, so I don't know exactly how I am getting these errors or what's causing them. I have even tried deleting the previous pointer used to see if thats what was causing it but it wasn't.
Please Halp.
Because you return a pointer to a local variable, and when that local variable goes out of scope you have a stray pointer.
And no, your allocation doesn't help, as you reassign the pointer to point to the local array, instead of copying into the allocated area. This of course means you also have a memory leak.
Regarding memory leak, you will still have a memory leak even when you fix the above problem. The reason being that you return from the function before you delete[] the pointer, and return returns from the function immediately, all code after a return statement is dead code. That means every time you call the function, it will allocate new memory which will never be free'd.
There are two obvious solutions to both the problems above: One is to allocate memory, copy the array into the allocated memory, and returning the pointer, and in the caller you do delete[] on the pointer.
The second solution is to pass in an array as argument, and use that instead of the local stats array.
p_stats is a pointer to int.
First you assign it to a newly allocated place in memory.
Then you move the pointer to point to local storage and return that. My guess is that you really wanted to return stats. Your options are:
Returns std::vector< int >. Probably simplest.
Modify your function to take a buffer to data and a length and fill it in.
Return std::array if available and you know it will be a fixed size of 6.
Although you could copy the data into p_stats then return that, it is not ideal because the calling function is then responsible to delete the data later.
If the fields have different meanings, you might want to create a struct with meaningful names for the values, and get your function to return that struct. e.g.
struct SpendAttribute // in header
{
int hp;
int endur;
int dmg;
int armor;
int agility:
int evade
};
SpendAttribute spendAttribute( int point )
{
SpendAttribute res;
// enter code here
return res;
}
There is a final option of putting the data into a smart-pointer like boost::shared_array<int> or you can use shared_ptr with an array-deleter.
For now, just return std::vector<int>

Is this behaviour of delete[] expected - deleting only the first two elements?

My code:
#include<iostream>
#include<cstdlib>
using namespace std;
int main()
{
int * p;
p = new int[5];
p[0] = 34;
p[1] = 35;
p[2] = 36;
p[3] = 44;
p[4] = 32;
cout << "Before deletion: " << endl;
for (int i = 0; i < 5; i++)
{
cout << p[i] << endl;
}
delete[] p;
cout << "After deletion: " << endl;
for (int i = 0; i < 5; i++)
{
cout << p[i] << endl;
}
}
If delete[] is supposed to delete all the memory blocks created by the new then why does only the first two elements get deleted here?
This is the output:
Before deletion:
34
35
36
44
32
After deletion:
0
0
36
44
32
One possible reason I could think of is that it removes the first two which some how makes the memory management think that the whole block is free to be reallocated again when needed. Though this is a complete guess on my part and I don't know the real reason.
There's no need to clear (as in change the value) of a deleted element, it only means that the allocator is free to use the space it occupied for whatever it wants, and that accessing the values results in undefined behaviour.
You have experienced a really nasty result of this, which is that some values remain unchanged, while successive runs of the same program might (and you should assume that will) have different results.
It is not the first two items deleted, but all of them. That memory area could now be reused by further new operation, but there is no guarantee what is left in that memory area.
It is completely possible that you would see different results for different machines, subsequent runs on the same machine, different compiler versions and so on. Just do not rely on it.
However, you are accessing a dangling pointer afterwards which is Undefined Behavior (shortly UB).
Just in case, if you call delete without the square brackets, all the memory is de-allocated, but destructors may not be called. That is also UB even though you do not have custom types in this case, just ints.
In your case, it is exactly the same UB behavior with delete as well as delete[], respectively. That is why you see the same results in both cases for your current runs, but then again, even that is not guaranteed.
Ideally, you would need to set them to zero, too, but really, you should consider using a smart pointer, like unique_ptr.
Q: If delete[] is supposed to delete all the memory blocks created by the new then why does only the first two elements get deleted here?
A: The conclusion is incorrect. Try the following:
#include <iostream>
struct A
{
A() : a(0) {}
~A() { std::cout << "Came to ~A(). a = " << a << std::endl;}
int a;
};
int main()
{
A* ap = new A[5];
for (int i = 0; i < 5; ++i )
{
ap[i].a = i;
}
delete [] ap;
}
I get the following output:
Came to ~A(). a = 4
Came to ~A(). a = 3
Came to ~A(). a = 2
Came to ~A(). a = 1
Came to ~A(). a = 0
A pointer is not magic. It is effectively an unsigned integer of machine word size which refers to a memory address. Changing the value of a memory location from whatever it is to 0 is not deleting anything. When you call delete or delete [] all you've done is told the memory allocator that you are done with that memory and it is free to do (or not do) whatever it wants with that memory. After you call delete, what might be in that memory is undefined, you have no right to expect it to contain anything in particular, and you have no right to access it. Accessing memory that has been freed is like entering an apartment that you moved out of that you still have a key to; you might get away with it or you might get an access violation.
For types with destructors, the memory allocator will call the destructor for each object in the block of memory before reclaiming the memory block. ints have no destructor, so there's nothing extra for it to do.
delete[] p releases the memory held by p, but doesn't (necessarily) overwrite it. The old data will remain there indefinitely.

Why use pointers in C++?

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.