What are pointers FOR?

Monkey Forums/Monkey Beginners/What are pointers FOR?

RedGTurtlepa(Posted 2016) [#1]
So, you make something like this in your "Main_Single.code" thing somewhere:

//Psuedo Code Yo....

int main()
{

H_WINDOW *windowMain = new H_WINDOW(//params)


}


So I just initialized(HOPEFULLY, I MEAN I MIGHTA TYPE THIS WRONG) a pointer called windowMain, which isn't a variable? or is it a variable with a memory address? I'm confused here, why wouldn't I just use windowMain and simply reference this. I've been told that if you do not master pointers you will be considered as the lowest tier programmer to ever exist, your very creations will rebel against you, and you will lament forever in your failure and pitiful understanding of not only game, but application development...... for all time.


But I'm kinda ok with that, but now I want to understand

A. Why I really want to know about them since theyre so good for you, not just in any languages, but ALL languages

B. Theyre super powerful and make things easier... than doing something straight forward apparently.

C. They streamline design and cut down on waste?

But here is my problem with pointers:

A. You keep referencing the same memory address, over and over... so its just a "glorified" way of passing a value? Why do I want to keep doing this? Why not assign values from values and free variables after I am done using them?

B. The main use of pointers is for memory management, or in the case of C being able to pass variables between functions since C doesnt have classes, only C++ does...

C. In the case of C++......... why? I'm dumb.


Seriously, I am stupid, please help, everyone I ask says I need to keep reading the same tutorials that I've already read, and to me it makes no sense. I mean 90% of all tutorials keep using pointers and thats in C++ only libs!

Perhaps I should go off the deep end, try and make apps without pointers and learn through trial and error as to why I need them in application development. Clearly I am an unknowing traveler, unfit for the inner sanctum of internet code champions.... clearly I am the problem.

Anyway, if anyone could break down the history of pointers, why I need them, and what they do INSTEAD of directly referencing variables between types/classes (apparently something C cant do, but something C++ CAN do, but still chooses not to do when using pointers... errm *scratch head*_ I'd be eternally grateful.. I can draw you really bad pixel art as a reward? Just tell me the genre.....


Gerry Quinn(Posted 2016) [#2]
You DON'T need them if you are using Monkey, or Java, or similar languages.

These languages use them 'under the hood', because when you reference an object you are actually passing a pointer. But they don't let you do fancy things with them as you can with C/C++. The fancy things can be great for making highly optimised code, but they can also give you great opportunities to make problems for yourself.

One important aspect of the difference is that Monkey / Java / C# etc. have 'garbage collection' which means you can forget about objects that can no longer be accessed. In C / C++, you have to make sure such objects get deleted when you're no longer using them. The Monkey-style languages reduce your ability to access and control objects exactly as you like - but in return, they make life easier in some respects by managing all the pointers.


RedGTurtlepa(Posted 2016) [#3]
Like, what fancy things? I don't see what can be fancy about passing something that never changes? Am I wrong here?


dawlane(Posted 2016) [#4]
I would suggest that you get a copy of Beginning C++ by Ivor Horton (he also has a book on C). And search the internet for pointer use. http://www.cplusplus.com/ should be a good place to start. Check out http://www.cplusplus.com/articles/z6vU7k9E/ for argument passing by value, reference and pointer.

> A. Why I really want to know about them since theyre so good for you, not just in any languages, but ALL languages
Not all computer languages support the use of pointers. Languages such as Monkey/Java/C# do all the memory management for you behind the scene, so you do not have to worry so much about memory or about pointers.

A thing to remember.
Other than programming directly in assembly language or machine code. All advanced languages will have run time libraries to do some of the dirty work.

> B. Theyre super powerful and make things easier... than doing something straight forward apparently.

What is a pointer? Well the definition is a variable that holds the memory address of another variable.


What does this mean? As modern operating systems allocate the memory that your application and it's data will use; there is no way for you to know where in memory a particular variable or data object is stored. This is where pointers come in. When you allocate memory with the new/malloc, it will return an address where this memory has been allocated. When you have finished doing what you need to do with that memory. You would use free()/delete.
The power of a pointer is that it will give you direct access to memory.

The fancy things Gerry Quinn speaks of are operating on data structures such as walking arrays, using linked lists (do a search on self modifying code as well). Look for "Data Structures and Algorithms for Game Developers". There should be a few books in print and as eBooks, as well as a few web pages on the matter.

You also need pointers for loading dynamic linked libraries. Without pointers programming a modern computer would be virtually impossible.

One thing to be aware of is that pointers are a powerful and wielding such power comes with a responsibility. It's very easy to crash a program or the operating system in some cases when not paying attention with the use of pointers. Reassigning a pointer without first freeing any memory that was assigned to it beforehand creates what is known as a memory leak.

You can find more videos on pointers. Just copy and paste the line below into a web browsers address bar.
https://www.google.co.uk/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=c%2B%2B+pointers&tbm=vid


RedGTurtlepa(Posted 2016) [#5]
no,thanks to you both, I THINK I got it now(that video I saw it before but didnt understand the difference between &(get address, use only with original value or to get any other variables memory address, I guess) *(get value at address stored in a pointer, dont use on non pointer initialized variable), someone should simply say "Pointers are C/C++ version of local variables."
So I can make a function:

//lazy syntax code
int DoMathWithAVar(int* varPassed) //passed into a temporary pointer.. do I initialize it here as NULL?
{
//I believe I could just work with varPassed but I'd rather not, so I guess this is rapidly passing a pointer to another pointer?
int* workMath = &varPassed;

*workMath += *workMath + mathChangeInValue;

Return *workMath; //or do I return
}


if this is the case, then I can see the use, especially in concerns of directly managing your own memory in the C/C++ language, perhaps this is what everyone keeps saying when they say "You must do it yourself if you use C/C++!!!"
ehh maybe anyway... well thanks this seems var simpler now that I had kind individuals spell it out for me.


dawlane(Posted 2016) [#6]
someone should simply say "Pointers are C/C++ version of local variables."
That would be wrong. Pointers are a special kind of data type. The amount of bytes assigned to a pointer depends of the compiler and the target CPU architecture. You should think of them as a memory address data type.

As for your function code. It wouldn't work. It would complain about conversion between data types. And as you are passing an address, you can only use de-reference. Trying to assign the parameter passed to a pointer variable would just make the pointer variable an alias.
int* workMath = &varPassed; // remove & to make it work as an alias.

See www.learncpp.com/. Chapters 6 and 7


RedGTurtlepa(Posted 2016) [#7]
So it is a memory data type, that can work with memory, and assign values to memory, and return values dereferenced from inside its memory that is stored or POINTED at from inside itself?

Ok, I get it. ....maybe.

So to get this straight, a pointer, holds a memory address, which can hold any value type aslong as the pointer is initialized as that type.

In storage, or within your program, a pointer is a special variable for holding references to location in your programs memory which hold datatypes. And other than the need for working directly with memory for reasons....we do this, generally, so we dont keep making new variables which can increase memory usage in C++ or similar languages? Or do we do this so we initialize pointers

Assuming all this is correct, why do alot of lib tutorials out there initialize new data types as pointers, and then work directly with them as an alias? Is that so they can easily reference the memory address later in some kind of clean up command?


Jesse(Posted 2016) [#8]
everything in computer memory has an address: code has an address variables have an address data has an address. the address is the position in memory where the variable, code or data is located. everything is stored as bits. Pointer only point to the location where a certain data type is stored regardless of its type declaration. variable names are used for the programmer to easily represent memory location for certain data types. with pointers you can access the data it points in any format. for example if you store an integer in memory you can access the address of the integer in bytes format. you can read the first and second byte of a 16 bit int by accessing it with byte ptrs.
>local a:int = 35
>local b:Byte Ptr = Byte Ptr(a)
b[0] would be the first part(8 bit) of the 16 bit integer
b[1] would be the second part(8 bit) of the 16 bit integer
to access "a" as an integer:
>local b:int Ptr = Int Ptr(a)
b[0] would access the whole integer.
b[1] would cause an error as it's beyond the position of the integer. its all a result of the integer ptr definition.
if b is a pointer, the address to where the variable "b" is pointing can also be changed like this:
>b = b + 1
as related to this last definition, in this case b will point to the next integer which is none existing or an address in memory which does not necessarily belong to an integer.
or
>b = 50
be careful with pointers because if you don't know what's in an address that's beyond the length of the stored data then you can easily crash the program or even the computer.

pointers are quite useful in languages that support them but have a potential to cause many problems in program design as the compiler is limited in the ability to check if a pointer variable is pointing to a valid data address. it's mostly left to the skill of the programmer to stay within the bounds of the ptr type.

another thing to note: if you are working with Apple operating systems and Windows operating systems. you need to learn about big Endian and little Endian. it's the way data types are stored in the computer by the operating system. do a google look up to find out more.


dawlane(Posted 2016) [#9]
So it is a memory data type, that can work with memory, and assign values to memory, and return values dereferenced from inside its memory that is stored or POINTED at from inside itself?

A pointer is a special data type/variable that can hold the memory address of another data object. When you declare a pointer; it must match the data type of the object that you wish to get the address of e.g
int x = 25; // data type is int
int *xPtr = &x; // declare a pointer to memory address of x. The pointer must be of type int as that is what the variable x is
char arr[5] = {'a','b','c','d','e',0}; // fixed array of data type char
char *arrPtr = arr; //same as char *arrPtr = &arr[0]. The compiler is smart enough to know that arr is an address to the first element, as the creation of a fixed (i.e hard coded) array automatically allocates memory and returns an address.

But there is an exception to this rule when declaring a pointer as type void. A void pointer is a generic pointer that can hold the memory address for any data type, but the penalty for doing so means that you have to remember the data type that you are pointing to and use data type casting in the dereferencing.

The C way to do this is
int deref = *(int*)voidPtr; // cast the void pointer back to an int and dereference

The C++ way is
int deref = *static_cast<int*>(voidPtr); // cast the void pointer back to an int and dereference

If you declared deref as a pointer and remover the deference specifier in front of the cast. You can then use deref as an alias and save typing the full cast as well as memory and speed of execution every time you wished to access the void pointer.
See www.learncpp.com/. Chapters 6.13

You can use a pointer for indirect access or as a handle to a data object/function. A pointer used as a handle can be used to call data object functions and manipulate data object members. When you load a shared library manually at runtime, you have to use the handle so you can create pointers to the functions that the shared library exports. You are basically getting the memory address of those functions. Shared libraries linked at compile time do not need to do this.

we do this, generally, so we dont keep making new variables which can increase memory usage in C++ or similar languages?
One thing you will need to know is how the operating system allocates memory for an application.
Here as a number of articles on the subject
http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/
https://www.usna.edu/Users/cs/aviv/classes/ic221/s14/lec/06/lec.html
https://en.wikipedia.org/wiki/Data_segment (you should follow the links for BSS, Call Statck and Code segment)

As you can see a lot of stuff get allocated to the stack by default. The stack has a limit, plus things get add to it and removed from it quite a lot. A pointer to something that may end up being removed and then using that pointer to accessed non existent data would throw an exception error and stop program execution. This can happen when the variable goes out of scope or overwritten.

You will always be creating variables. Be they pointers or otherwise in the languages that support them.

The memory usage side.
If you create a big data structure on the stack; then you will run out of stack space if you have to create an array of such structures. You would use the new operator to allocate the memory, which returns a memory address that you would store in a pointer (you can call this a handle). To access this new data object/structure(s) on the heap via pointers, you use member of pointer(->) operator in C/C++.
e.g.
class MyClass
{
int val = 5;
public:
int functionInOjbject( int v ){
return this->val += v;
}
}

MyClass *ptr2myclass = new MyClass;
int result = ptr2myclass->functionInOjbject(5);
delete ptr2myclass; // Finished with it, so release the memory allocated or you could end up with a memory leak.

Note as you can declare pointers as arrays (the basic container type); there is nothing from stopping you from allocating a number of data objects.

A couple of related topics
http://www.tutorialspoint.com/cplusplus/cpp_references.htm
http://www.tutorialspoint.com/cplusplus/cpp_pointers.htm
http://www.thegeekstuff.com/2013/05/cpp-reference-variable/

Function parameters.
If you passes a variable holding a data object by value; meaning not as a (*)pointer or by (&)reference. Then you suffer a performance hit in speed and memory if the data object is big. Passing by value makes a copy of the object. This means you are working on a copy and not the original. You would have to return the whole copied object; in affect a new object. Wasteful if you only need to make a minor change or access a few data members.

I think that the links below should explains the difference of by value, by reference and by pointer.
https://www3.ntu.edu.sg/home/ehchua/programming/cpp/cp4_PointerReference.html
http://www.tutorialspoint.com/cplusplus/cpp_functions.htm

Or do we do this so we initialize pointers
When you declare a pointer you should initialise it immediately either with the address of the variable that you want it to point to, or as NULL or 0. An uninitialised pointer will have a random data and using it like that can have unusual effects or crash the program/system.


RedGTurtlepa(Posted 2016) [#10]
Ah well, no one ever told me all this, it wasn't explained to me very well and having used other languages that apparently handle all the pointers behind the scenes.
So all current non C/C++ languages like BASIC and C# use pointers behind the scenes to handle data(variables/code/types/etc) you make in a way that manages the memory efficiently just like in C++? Wow. Seems like theyre important to a basic understanding of any programming language then. I had no idea what they were for and how integral it was to use them in programming. Thanks again everyone. I think I got it now, atleast I am much less afraid of using them beyond the fact using them wrong is not wise.


dawlane(Posted 2016) [#11]
If you read Pointer_(computer_programming). It will show you a number of programming languages; what memory access methods they use and a few examples.

Edit: Not on topic, but worth knowing.
If you have ever seen the function main of a windows GUI application (aka application entry point). You will see that it's defined as

int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
);

Sometimes you see CALLBACK as WINAP. These are aliases for what is know as a calling convention.
Another link to read on these.
http://www.codeproject.com/Articles/1388/Calling-Conventions-Demystified


RedGTurtlepa(Posted 2016) [#12]
I have a question
//
bool* boolVar = new bool;
///
    bool** _boolVar = &boolVar;
    cout << endl << _boolVar << " // " << &boolVar<< endl << &_boolVar;
    cout << endl << *boolVar;
    cout << endl << **_boolVar;
    cout << endl;



This does everything I want, and I can understand evrrything I wanted to about pointers (ehhh, less than more) but I can use them a bit more now and I am reading those tutorials you linked me but I still cant understand, why does bool** _boolVar need to be declared as a double pointer? (or wghatever theyre called) is it because the memory address is a pointer originally?

Why does bool* _boolVar = boolVar work?
bool** _boolVar || bool*_boolVar = *boolVar does not work.


also a smal question when casting a passed array back into a type why does TYPE* (*typeVarName)[int] become equal to TYPE* typeVarName[int][int] is it because the original array of types degraded back into a pointer like ive read arrays being passed degrade into? and then C++ simply adds the extra dimensions? Is it purely syntax rules here?

I have also understanding of how you can read multi-dimensional arrays if this helps:

arrType[int][int] == {{1, 2, 3, 4}, {1, 2, 3, 4}, {1, 2, 3, 4}, {1, 2, 3, 4}} == {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}

but I am confused and I did read that article that had an example but I figure I'd ask again.... eh sorry.

Anyway thanks I can atleast use and work with pointers, they do make life much more entertaining since I have a very nice datatype to work with.

Oh And about the first example, I did some testing and it does appear everything gets its own memory address, the pointer, the variable it points to, the pointer of the poiinter, the sun, the moon, the stars........... it was a realm eye opener.


dawlane(Posted 2016) [#13]
I will try to answer your questions.
> why does bool** _boolVar need to be declared as a double pointer?
This is because you are making a pointer to a pointer, which in turn points to the original variable. This is another form of indirection. You can create as many indirection's as you like e.g bool ***_boolBar. But it would get a bit silly and a lot harder to keep track of whats going on.

So why use a pointer to a pointer? I can think of two reasons.
1) Creation and manipulation of Dynamic N Multi-Dimensional Arrays.
2) Being able to affect the pointer that's being pointed too.

The second would be more common with the use of functions. When you call a function; you are passing by value no matter whether if you pass by reference or by pointer. You are still making a copy of whats been passed.
For example if you pass an object that's 1 mega byte in size by value; then you are copying 1 mega byte of data, where as if you use call by reference or pointer. You are only copying over that reference or pointer. This could be 4-8 bytes depending on the operating system architecture. As you are working on a copy which will be local to that function, any changes will not affect the original. But there are times when you may need to make a change to the pointer it's self while in a function That's when you need a pointer to a pointer. When doing this, you must preserve the original address if you allocated memory on the heap or suffer a memory leak.

>bool** _boolVar || bool*_boolVar = *boolVar does not work.
You are trying to use a logical OR operator on a declaration. C/C++ and a few other languages are a strong typed language. Meaning that variables and data types must be predefined. Plus the the compiler would complain about data type conversion.

>also a smal question when casting a passed array back into a type why does TYPE* (*typeVarName)[int] become equal to TYPE* typeVarName[int][int] is it because the original array of types degraded back into a pointer like ive read arrays being passed degrade into? and then C++ simply adds the extra dimensions? Is it purely syntax rules here?

That one would be tricky to answer. If it compiles then you should have got a warning in the build console explaining why.

> I have also understanding of how you can read multi-dimensional arrays if this helps:
arrType[int][int] == {{1, 2, 3, 4}, {1, 2, 3, 4}, {1, 2, 3, 4}, {1, 2, 3, 4}} == {1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4}

Yes they would be treated as a block. You should be able to examine memory when debugging or using a disassembler.
Edit: A small example.

Now the same program, but with added machine code disassembly. Note that the memory addresses will be different on another machine and this is gdb output.
If you want to see actual assembly code. The use the compiler via the command line terminal passing the appropriate compiler option to generate assembler only.

The bits of interest are the rbp-0xXX in the mov BYTE PTR instructions where the arrays are being defined. If you declared a fixed array out side of a function; then the compiler pre-allocates the memory in the .data section and no need for the x86 instruction mov.