Login Register


Pointers filter_list
Author
Message
Pointers #1
Introduction

If you have seen some C++ code there is a chance you might have seen something like this:
Code:
<DataType>* myPointer;
The datatype tag can hold int, char, ...
When you see this syntax it means that there has been defined a pointer, an object that can write to or read from specific memory addresses. This will make it possible to access different variables with the same variable (pointer).

Memory

Most things that the computer is using is stored in the memory, this means that when you load your program, every single piece of data from the exe will be stored in the memory. If you do not found out already, I'm talking about the RAM (Random Access Memory) memory. Every single piece of data (of 8 bits / 1 byte) has a specific address so the computer knows where to look, an address might look like this: 0x43eea4 (hexadecimal form), or even like this: 4 452 004 (decimal form of the previous hexadecimal form).

If you still don't really understand the concept of these memory addresses, here is a simplified version:

Your memory is one large street, at the street there are various houses that each have their own corresponding house number. This can for example be used to receive mail (data). When your program wants to read a specific address it will ask the computer to tell him who is living at the house with that specific number (for example a char with a value of 'a'). When the program wants to write to a certain house, it will tell the new inhabitant (for example a float with a value of 15.256) to go and live at the house with that specific number. The inhabitant who has been living there until now will simply disappear.

Pointer syntax

By now you should know how a program can access certain memory addresses. With a bit of code you can ask the computer to do something with these memory addresses as wel by using a pointer. First we will define a pointer, you can do that like this:
Code:
int* myPointer;
Now we defined an integer pointer, because a standard integer is formed using 32 bits (4 bytes) and a memory address (house) can hold 8 bits (1 byte). This means that when you are using an integer pointer it will use 4 different memory addresses to form a single number. Each memory address (house) will be 1/4 of a number and by using these 4 houses you'll have a standard integer number/value.

Here is the code to initialize an integer pointer:
Code:
int myNumber = 10; int* myPointer = &myNumber;
The asterisk (*) after the "int" means that you're making an integer pointer as we've already seen, the &-sign in front of the "myNumber" however, means that you're asking the address. Because myNumber is a normal variable standard it will give you it's value (10), but when we want to attach the pointer to the memory address of the pointer we will need the address, not the value. You can test this and output the resulting memory address or value like this:
Code:
int myNumber = 10; int* myPointer = &myNumber; std::cout << myPointer; // Will output the memory address std::cout << *myPointer; // Will output the value 10
As you can see is the standard output of the pointer-object the address to which it is attached, when you want to get the value of the attached address an asterisk (*) will have to be placed in front of it.

Implementation

Now when we want to for example change the value of the memory address, we can use the pointer almost like all the other normal variables:
Code:
int myNumber = 10; int* myPointer = &myNumber; std::cout << myNumber << " " << *myPointer << endl; // Will output 10 twice *myPointer = 11; std::cout << myNumber << " " << *myPointer; // Will output 11 twice
As you can see, if you want to change the value using a pointer, you simply access the value by using the asterisk in front of the pointer (as seen before) and tell it what to do with it (= 11, ++, += 2, ...). When we later access the value of myNumber it will be the value that the pointer gave it, because we changed the value of the address, i.e. every object that uses this address will read the same value (11).

Now, what would happen if you for example add 1 with the address (not the value)? When you do this, the address will automatically be located at the next address but with an integer it will not be like this: 0x28ff44 -> 0x28ff45.
As you can see the address is added simply added by one, but when you use an integer it will not be added by 1 but by the amount of addresses/houses the data type needs to display a value, this means that an integer pointer will not go to the next house, but to 4 houses further.

Example

Now that you know the basic operations and syntax of a pointer I will give a small example code using all the previous mentioned subjects to make a memory scanner:

Code:
#include <iostream> #include <bitset> using namespace std; int getSize(string out){ cout << "How many " << out << " should be scanned? "; int ret; cin >> ret; return ret; } void useInt(){ int* i; int size = getSize("integers (4 bytes)"); for(int a = 0; a < size; a++){ cout << (i + a) << " (" <<(long)(i + a) << ")" << ": " << *(i + a) << (*(i + a) == 0 ? " (probably not being used)":"") << endl; } } void useFloat(){ float* i; int size = getSize("floating points (4 bytes)"); for(int a = 0; a < size; a++){ cout << (i + a) << " (" <<(long)(i + a) << ")" << ": " << *(i + a) << (*(i + a) == 0 ? " (might not be used)":"") << endl; } } void useDouble(){ double* i; int size = getSize("double precision floating points (8 bytes)"); for(int a = 0; a < size; a++){ cout << (i + a) << " (" <<(long)(i + a) << ")" << ": " << *(i + a) << (*(i + a) == 0 ? " (might not be used)":"") << endl; } } void useChar(){ char* i; int size = getSize("characters (1 byte)"); for(int a = 0; a < size; a++){ cout << static_cast<void *>(i + a) << ": " << *(i + a) << (*(i + a) == 0 ? " (might not be used)":"") << endl; } } void useBinary(){ char* i; int size = getSize("binary values (8 bits)"); for(int a = 0; a < size; a++){ cout << static_cast<void *>(i + a) << ": " << bitset<CHAR_BIT>(*(i + a)) << (*(i + a) == 0 ? " (might not be used)":"") << endl; } } void doMainPurpose(){ cout << "What data type (int, float, double, char, binary) should be used?\n"; string in; cin >> in; if(in == "int" || in == "float" || in == "double" || in == "char" || in == "binary"){ if(in == "int"){ cout << "\n--> Using integers! "; useInt(); } else if(in == "float"){ cout << "\n--> Using floating points! "; useFloat(); } else if(in == "double"){ cout << "\n--> Using double precision floating points! "; useDouble(); } else if(in == "char"){ cout << "\n--> Using characters! "; useChar(); } else if(in == "binary"){ cout << "\n--> Using binary! "; useBinary(); } else{ cout << "Oops.. something went wrong! What did you do now?"; } }else{ cout << "\n--> Data type " << in << " not recognized, using char. "; useChar(); } } int main(){ doMainPurpose(); system("PAUSE"); return 0; }

I hope that everything is clear, if there are any problems make sure to ask!
[Image: 2YpkRjy.png]
The extremity is only the commencement of further progress.

Reply

Pointers #2
Introduction

If you have seen some C++ code there is a chance you might have seen something like this:
Code:
<DataType>* myPointer;
The datatype tag can hold int, char, ...
When you see this syntax it means that there has been defined a pointer, an object that can write to or read from specific memory addresses. This will make it possible to access different variables with the same variable (pointer).

Memory

Most things that the computer is using is stored in the memory, this means that when you load your program, every single piece of data from the exe will be stored in the memory. If you do not found out already, I'm talking about the RAM (Random Access Memory) memory. Every single piece of data (of 8 bits / 1 byte) has a specific address so the computer knows where to look, an address might look like this: 0x43eea4 (hexadecimal form), or even like this: 4 452 004 (decimal form of the previous hexadecimal form).

If you still don't really understand the concept of these memory addresses, here is a simplified version:

Your memory is one large street, at the street there are various houses that each have their own corresponding house number. This can for example be used to receive mail (data). When your program wants to read a specific address it will ask the computer to tell him who is living at the house with that specific number (for example a char with a value of 'a'). When the program wants to write to a certain house, it will tell the new inhabitant (for example a float with a value of 15.256) to go and live at the house with that specific number. The inhabitant who has been living there until now will simply disappear.

Pointer syntax

By now you should know how a program can access certain memory addresses. With a bit of code you can ask the computer to do something with these memory addresses as wel by using a pointer. First we will define a pointer, you can do that like this:
Code:
int* myPointer;
Now we defined an integer pointer, because a standard integer is formed using 32 bits (4 bytes) and a memory address (house) can hold 8 bits (1 byte). This means that when you are using an integer pointer it will use 4 different memory addresses to form a single number. Each memory address (house) will be 1/4 of a number and by using these 4 houses you'll have a standard integer number/value.

Here is the code to initialize an integer pointer:
Code:
int myNumber = 10; int* myPointer = &myNumber;
The asterisk (*) after the "int" means that you're making an integer pointer as we've already seen, the &-sign in front of the "myNumber" however, means that you're asking the address. Because myNumber is a normal variable standard it will give you it's value (10), but when we want to attach the pointer to the memory address of the pointer we will need the address, not the value. You can test this and output the resulting memory address or value like this:
Code:
int myNumber = 10; int* myPointer = &myNumber; std::cout << myPointer; // Will output the memory address std::cout << *myPointer; // Will output the value 10
As you can see is the standard output of the pointer-object the address to which it is attached, when you want to get the value of the attached address an asterisk (*) will have to be placed in front of it.

Implementation

Now when we want to for example change the value of the memory address, we can use the pointer almost like all the other normal variables:
Code:
int myNumber = 10; int* myPointer = &myNumber; std::cout << myNumber << " " << *myPointer << endl; // Will output 10 twice *myPointer = 11; std::cout << myNumber << " " << *myPointer; // Will output 11 twice
As you can see, if you want to change the value using a pointer, you simply access the value by using the asterisk in front of the pointer (as seen before) and tell it what to do with it (= 11, ++, += 2, ...). When we later access the value of myNumber it will be the value that the pointer gave it, because we changed the value of the address, i.e. every object that uses this address will read the same value (11).

Now, what would happen if you for example add 1 with the address (not the value)? When you do this, the address will automatically be located at the next address but with an integer it will not be like this: 0x28ff44 -> 0x28ff45.
As you can see the address is added simply added by one, but when you use an integer it will not be added by 1 but by the amount of addresses/houses the data type needs to display a value, this means that an integer pointer will not go to the next house, but to 4 houses further.

Example

Now that you know the basic operations and syntax of a pointer I will give a small example code using all the previous mentioned subjects to make a memory scanner:

Code:
#include <iostream> #include <bitset> using namespace std; int getSize(string out){ cout << "How many " << out << " should be scanned? "; int ret; cin >> ret; return ret; } void useInt(){ int* i; int size = getSize("integers (4 bytes)"); for(int a = 0; a < size; a++){ cout << (i + a) << " (" <<(long)(i + a) << ")" << ": " << *(i + a) << (*(i + a) == 0 ? " (probably not being used)":"") << endl; } } void useFloat(){ float* i; int size = getSize("floating points (4 bytes)"); for(int a = 0; a < size; a++){ cout << (i + a) << " (" <<(long)(i + a) << ")" << ": " << *(i + a) << (*(i + a) == 0 ? " (might not be used)":"") << endl; } } void useDouble(){ double* i; int size = getSize("double precision floating points (8 bytes)"); for(int a = 0; a < size; a++){ cout << (i + a) << " (" <<(long)(i + a) << ")" << ": " << *(i + a) << (*(i + a) == 0 ? " (might not be used)":"") << endl; } } void useChar(){ char* i; int size = getSize("characters (1 byte)"); for(int a = 0; a < size; a++){ cout << static_cast<void *>(i + a) << ": " << *(i + a) << (*(i + a) == 0 ? " (might not be used)":"") << endl; } } void useBinary(){ char* i; int size = getSize("binary values (8 bits)"); for(int a = 0; a < size; a++){ cout << static_cast<void *>(i + a) << ": " << bitset<CHAR_BIT>(*(i + a)) << (*(i + a) == 0 ? " (might not be used)":"") << endl; } } void doMainPurpose(){ cout << "What data type (int, float, double, char, binary) should be used?\n"; string in; cin >> in; if(in == "int" || in == "float" || in == "double" || in == "char" || in == "binary"){ if(in == "int"){ cout << "\n--> Using integers! "; useInt(); } else if(in == "float"){ cout << "\n--> Using floating points! "; useFloat(); } else if(in == "double"){ cout << "\n--> Using double precision floating points! "; useDouble(); } else if(in == "char"){ cout << "\n--> Using characters! "; useChar(); } else if(in == "binary"){ cout << "\n--> Using binary! "; useBinary(); } else{ cout << "Oops.. something went wrong! What did you do now?"; } }else{ cout << "\n--> Data type " << in << " not recognized, using char. "; useChar(); } } int main(){ doMainPurpose(); system("PAUSE"); return 0; }

I hope that everything is clear, if there are any problems make sure to ask!
[Image: 2YpkRjy.png]
The extremity is only the commencement of further progress.

Reply

RE: Pointers #3
I will give you a feedback later , there are things that needs to be changed , I have some other work so later I will reply later
[Image: OilyCostlyEwe.gif]

Reply

RE: Pointers #4
I will give you a feedback later , there are things that needs to be changed , I have some other work so later I will reply later
[Image: OilyCostlyEwe.gif]

Reply

RE: Pointers #5
We really need to kill all the usage of system() calls in C/C++... I've seen it many times now but I don't think people realize how bad it is, aside from the fact that it limits your binary to Windows only. I would love to have a program that I want to crack, do that.
ArkPhaze
"Object oriented way to get rich? Inheritance"
Getting Started: C/C++ | Common Mistakes
[ Assembly / C++ / .NET / Haskell / J Programmer ]

Reply

RE: Pointers #6
The explanation is fine, i believe that you missed a step however. You should add why in a C or C++ program you should use pointers or references. That is to say, when you pass a parameter to a function by value then there will be no side-effect, with pointer you actually can make side-effect on the invoked variable
Everything is relative

Reply

RE: Pointers #7
The explanation is fine, i believe that you missed a step however. You should add why in a C or C++ program you should use pointers or references. That is to say, when you pass a parameter to a function by value then there will be no side-effect, with pointer you actually can make side-effect on the invoked variable
Everything is relative

Reply

RE: Pointers #8
Like ArkPhaze said, system() is terrible. It's just sad that few c++ book teach to use system().

Reply

RE: Pointers #9
More over the system function can also lead to a quite sophisticated buffer overflow attack. By the way i believe that this post should be considered related to pointers explanation and not focusing too much on the rest Smile
Everything is relative

Reply

RE: Pointers #10
I suggest you to prototype your functions. It makes your code easier to read.

Reply







Users browsing this thread: 1 Guest(s)