Again here i am because the course material for C++ was not taught very well at all. The question gives use several function definitions and calls to these functions and expects us to state the output and what exactly is going on. I have executed these functions and tried to come up with some rationale to what is happening but if someone could help me out that i would be very grateful.
function definitions (The names are all as given. I know the names are not very good):
void MyIncrementFirst(int * i) {
(*i)++;
}
void MyIncrementSecond(int i) {
i++;
}
void MyIncrementThird(int & i) {
i++;
}
void MyIncrementFourth(int ** i) {
*i = new int(0);
}
void MyIncrementFifth(int *& i) {
i = new int(69);
}
The calls to these functions have been defined as:
int * a = new int(42);
cout << "Result" << endl;
MyIncrementFirst(a);
cout << "first " << *a << endl;
MyIncrementSecond(*a);
cout << "second " <<*a << endl;
MyIncrementThird(*a);
cout << "third " <<*a << endl;
MyIncrementFourth(&a);
cout << "fourth " <<*a << endl;
MyIncrementFifth(a);
cout << "fifth " <<*a << endl;
Which produces the following:
first 43
second 43
third 44
fourth 0
fifth 69
Some of this syntax i have not seen before (e.g. *&) so i maybe completely wrong here.
First:
This seems simple enough. I am passing in a pointer to an integer, and then de-referencing the pointer and incrementing its value, so instead of incrementing the pointer i am incrementing the actual value it is pointing to. No memory allocation is used, and this function uses pass-by-reference in order to modify the value.
Second:
This is similar to the above, as the pointer is de-referenced to get the integer value from the pointer rather than the memory address. Now this function uses pass-by-value so a copy of the variable is used in the functions execution. This means that incrementing a here, will have no impact on the variable you passed in, the value of a will remain as 42, but the copy of the passed in variable will have its value changed to 43 during the functions execution.
Third:
My understanding is that the '&' operator is basically saying 'the memory address of ...' so this function will take the memory address of the passed in pointer, locate the value it points to an increment this by one. That is why 43 is printed. This is using pass-by-reference.
Fourth:
If i remember correctly the '**' syntax means a pointer to a pointer. This means that when passing &a to the function you are passing the memory address of the pointer so when you de-reference this pointer and set its value to a new int(0); you are actually overwriting the exiting data at this address (42 in this case) so the value 0 is printed. This uses pass-by-reference.
fifth:
I have not seen this syntax before (*&). I have looked up this syntax and i think it is basically saying 'pass me by reference not value' so it seems to be the same as de-referencing the pointer as mentioned earlier. Again, because this is pass-by-refence not value when the value is set to a new int(69); the current data at that location is overwritten thus 69 is outputted.
Edit: Forgot to include my question! I want to know if my thinking is correct, this is all exam prep so i want to be sure i am doing it correctly.I just want to make sure my logic is correct and if i have done anything wrong or missed anything would somebody be able to steer my in the right direction
Edit: (based on some commenter feedback)
Everything you have is mostly correct, save some confusion on your output values. However, what you have in #4 and #5 is actually not overwritten data, it's actually new data at a new address, which is assigned to the variable i. This is part of what an earlier commenter said about a potential for a memory leak. Since you're not deleting the old address before assigning a new one, that's where it could occur.
The &* syntax in the last one is a reference to a pointer. It's essentially the same as int** except you don't pass &a as the argument, it's just a
What you have there for number 5 is basically correct, but the reasoning behind it is missing the meaning of &*
You might want to clarify if you've run each of these function calls sequentially or one at a time, since your output is incorrect if you'd indeed run them sequentially as written.
Related
So, as of now, it seems to be impossible to actually modify a "const" value in C++ (tested in VS 2017).
const int a = 5;
int* ptr = (int*)&a; // Method 1
*((int*)(&a)) = 6; // Method 2
int* ptr = const_cast<int*>(&a); // Method 3
*ptr = 55;
cout << a << "\t" << &a << endl;
cout << *ptr << "\t" << ptr << endl;
Result:
5 SOMEMEMORYADDRESS
55 SOMEMEMORYADDRESS
Anyone got any idea what else can be tried to achieve the effect? Really curious how it is possible to have 1 memory address (at least according to the console) with 2 values.
Please note: there are topics like this for older C++ versions (and they used to work in the past - but they don't, anymore).
Really curious how it is possible to have 1 memory address (at least according to the console) with 2 values.
It's because you invoked undefined behavior. The C++ standard, from C++98, has expressly forbidden you from modifying an object that is declared const. And the standard has a catch-all statement such that if you do anything which causes modification of a const object, you get undefined behavior.
Because modifying an object declared const is UB, the compiler is free to assume that this object will never be modified. So, since the compiler can see that a is const and it is initialed to 5, it is 100% valid for the compiler to at compile time replace everything which revers to this object with 5. So when you do cout << a, the compiler is free to not bother to access memory; it can just do cout << 5.
If you did something to modify the memory behind a, that's UB, so the compiler doesn't have to care about what happens in that case.
they used to work in the past - but they don't, anymore
No, they never "worked". They merely just so happened to do what you thought they should. But C++ never guaranteed that compilers would behave in this way, so you have no right to complain about compilers changing that behavior now.
I had to write a program that declares char text[16]; and int number; and then fills it with input from the user. Then I have to call another function (without passing anything) and recall that data from the stack and display it.
I was able to find both of them
// This is the function that is called without passing any variables
int number;
char text[16];
cout << *(&text + 5) << endl; // This outputs the correct text but I can not figure out how to assign it to text
number = *(int*)(&number + 20); // This works and outputs the correct number and saves correctly to int number;
cout << "\tnumber: "
<< number
<< endl;
cout << "\ttext: "
<< text
<< endl;
I would like to know if there is a way to transfer the text from *(&text + 5) to char text[16];
What you are doing is going to result in undefined behavior. Depending heavily on the compiler and therefore in turn on the architecture. The proof being that when I compile and run your code with different optimization flags I get different results. Check out https://en.wikipedia.org/wiki/Buffer_overflow
The first expression *(&text + 5) evaluates to taking the address of the text pointer in memory, adding 5 to it and then dereferencing that to get a character value that is stored at that location. This can be pretty much anything on the stack at that time.
&number + 20 will definitely go off the "visible" stack, this is pointer arithmetic and will result in you adding 20*sizeof(int) to the pointer to the memory address of number on the stack.
If this is what you are intending to do then you should probably use strcpy as suggested by #JafferWilson
From reading the comments on the answer by Curious the answer is:
There is no proper way to read local variables in another function in C++ without passing them (or pointers to them or references to them) as parameters (or within objects you pass as parameters).
You can assign file scope (so called global) variables and read them in other functions. That is almost always a bad idea.
I get the feeling you might be coming from an assembler programming background to even try this sort of thing. You need to surrender a bit more to the structured programming paradigm.
I was writing a simple program to test how the scope of variables works, but I'm obtaining unexpected results, so I was hoping you could give me an hand to understand them.
I compiled this code
#include<iostream>
using namespace std;
void myFunction1()
{
int e;
cout << e << endl;
e++;
cout << e << endl<<endl;
}
int main()
{
cout << "MAIN" << endl;
int a,b,c,d;
cout << "a= " << a << endl;
cout << "b= " << b << endl;
cout << "c= " << c << endl;
cout << "d= " << d << endl<<endl;
cout << "MY_FUNC" << endl;
myFunction1();
myFunction1();
myFunction1();
}
and obtained this output
MAIN
a= -1617852976
b= 32767
c= 0
d= 0
MY_FUNC
32675
32676
32676
32677
32677
32678
So, there are two things I really don't understand
1) In the main() function I'm creating 4 int variables (a,b,c,d) WITHOUT initializing them, so I expect them to assume a different value each time I run the code. Strange thing is, the first variable (a) is always different, while the others always assume the same values (b=32767, c=d=0)
2) The function output is even stranger to me.
Again, I'm creating a variable e without initializing it, so the first time it assumes a random value (in the example, e=32675).....then, I increase it by one, so that it prints 32675 and 32676, and that sounds right.
But how come the second time I call the function, e keeps the previous value (32676)? I thought e was created each time I call myFunction1() and deleted at the end of the function, so that e assumed a different random value each time (since I don't initialize it). Why is the value of e stored even if the variable goes out of scope?
Uninitialized primitive values are simply not defined. They can have any value.
It is an undefined behavior. That's why it doesn't make any sense to analyze the behavior of this program.
In the main() function I'm creating 4 int variables (a,b,c,d) WITHOUT initializing them, so I expect them to assume a different value each time I run the code
This assumption is flawed. They may have a different value each time you run the code, but they may not. Anything could happen. The point of UB is that you should drop all your assumptions.
But how come the second time I call the function, e keeps the previous value (32676)? I thought e was created each time I call myFunction1() and deleted at the end of the function, so that e assumed a different random value each time (since I don't initialize it)
It does. If you replace "random" for the more correct "arbitrary", then the results you're seeing fit that pattern just fine.
It's just pure luck, and comes down to the state you're leaving unclaimed memory in at each stage of your program's execution.
A good way to help you understand this is to explain in terms of memory allocation.
When you run a program, a certain amount of memory that is not used is assigned to your variable.
Computers are lazy, the best way to delete a data is to forget where it is stored. When you assign a chunk of memory to a variable, you are telling the computer to remember where that certain data belongs to.
If it so happens that it was used prior to you assigning the memory to the variable, it will simply read (let's say 4 bytes for a common machine) and get the data from that location.
Hope that this helps =)
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>
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.