- I love C/C++, so here is a continuation of the tutorial.
Warm-Up lesson
If your program has a loop, then it might take up 100% of the CPU. To avoid that use
Code:
sleep(how long, in unsigned long, ms);
That command tells the CPU to forget about your program for
ms time and then come back. So if I do sleep(1000); then your program will pause at that place for ~1 second while the CPU goes ahead and either idles or works on other programs. It is a good idea to have a sleep command in a loop if your program does not need full use of the CPU.
For example, I am working on a cryptographic instant messenger ( so I could chat with my friends without being afraid of RIAA listening in). We don't want it to eat all the CPU resources. So we are telling it to check for incoming messages every 50 ms. (sleep(50)
Random Tidbit
NULL or null is actually 0 in C++. They are exactly the same thing, which is why it is safe to use 0/NULL interchangeably. It is actually declared in one of the header files that NULL is 0. (or is it (void*) 0? )
In java it is NOT the same thing. I learned it the hard way...
Lesson 8 – structures.
What if we are coding a game and want to have some kind of a place to store the status of lets say.... players in a game? We would use a structure. A structure is simply a combination of different types of variables. Here is an example:
Code:
struct player { char name[24]; int life; int numberOfPiecesLeft; float location}
The above code will create a structure player that has the specified variables in it. It groups them together. After we declare the structure, we can now declare the actual data storages. You can have structures inside of structures, functions and classes.
So we will do:
Then we will have pl1 and pl2. Now, in order to access a variable in a structure we use periods. So if we want to initialize the top code, we will do:
Code:
pl1.life=100; pl2.life=99; pl1.numberOfPiecesLeft=1;...
This is also used in a lot of headers by different headers/OSes. For example,
Code:
//from winsock2.h
struct sockaddr_in {
short sin_family;
u_short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
So, if we want to have a sockaddr_in, we would do something like this:
Code:
sockaddr_in mySocket;
mySocket.sin_family=2;
mySocket.sin_port=122;
mySocket..sin_addr.WhateverIsInsideOfSIn_addrStruct;
Lesson 9 – memory/pointers, in theory
Just what is memory? Computers' current memory is a sequence of 1's and 0s that are represented differently. You probably knew this already. So... what does that mean for you? Well, lets look at something you got familiar with: the integer. If you do int myInty = 0, then what does the PC see? It sees 4 bytes (so 32 bits). It sees 0000 0000 0000 0000 0000 0000 0000 0000. Now, you do not need to learn how to convert, because if you will use it then you will remember it.
Now if we have a char ohMyChar. Thats one byte, so it would be 0000 0000.
Pointer. They come next. A pointer is just that – it POINTS to the memory address. In itself, its usually an int size. So, on my system all my pointers are 4 bytes. Example: if I declare this...
Code:
int realInt=200;
int *ptr = &realInt;
realInt is just a location that contains 200. ptr is a number (like 0x22ff6c) that the CPU reads to get to that number. *ptr will give back 200.
Pointers are actually numbers that hold a value of the memory they are accessing. But in order to have the memory to use we have to either tie a pointer to somewhere (like above) or ask the OS to give us RAM.
Lesson 10 – The Big Ones, lesson 9 in practice
Normally if you define data for your program, it gets taken from stack. But if you want to be able to allocate RAM while your program is running, you would need to do that manually.
Here is what you do need to learn: malloc/calloc/realloc , and free.
Believe me, asking OS for RAM is extremely easy. The hard part is giving it back appropriately and actually using the RAM. The easiest way to explain this would be to use an example.
So, relax and enjoy the story.
You are the lead programmer of google. You are given an assignment: read some information from a file. So you go ahead and google (oh, the irony!) for C++ file handling. Then you open the file and think about where you are going to store all that information to. You could do something like
But what if the file is 1025 bytes in length? So you decide that you need to malloc some RAM from Windows/ Linux. Requesting memory from OS is really easy, all you do is
Code:
malloc(howMuchRamYouWantInBytes);
and the OS will gladly return a pointer to that RAM. If the pointer equals NULL/0 then you know that you wanted too much or the OS did not like you well enough (not enough RAM).
Now, in C++ (unlike JAVA) OS will attempt its hardest to give you all you ask it for. If you accidentally ask the OS for 1 gig of RAM, then it won't ask you what you need it for. It will happily allocate 1 gig of ram and send a pointer that points to one gig of RAM your way.
If you want to see the effect that it can have then try the following code while looking at your task manager RAM usage. And be ready to kill the program once it eats some RAM. After you kill it, Windows will attempt to clean up all wasted RAM.
Code:
while(1)
{
malloc(1000*1000); // eat some RAM
Sleep(100); // But not too fast
}
Now that you have seen the following example, make sure never to code the above way.
. There a couple ways of rules you have to follow. Here is what good malloc usage has to be:
Code:
int/char/long/struct... *myPtr = malloc(amountOfStuff * sizeof(int/char/long...));
if(NULL== myPtr) // if malloc returns 0/NULL, then something bad happened
{ // throw an out of RAM error with report of how much ram you tried to eat
}
//Use myPtr data here.
free(myPtr); // Frees the RAM. A MUST step
So, by now you know how to ask OS for RAM and how to receive it.
You also know the free(ptr), which gives memory back to OS.
The only thing left for the lesson is calloc and realloc.
Code:
ptr = calloc(number of stuff to do, bytes of each stuff);
That is then initialized to 0.
Code:
ptr = realloc(ptr, size- same as malloc);
Realloc is a much more interesting function it allows for us to increase or decrease the RAM usage as needed. So, lets say that we have a pointer that points to 20 Mbs of RAM. Now we only need 10 Mbs. A call to realloc will free the last 10 mbs without touching the first 10
Lesson 11, or what we actually do with those
Soon to come. - memset, memcpy, memmove and the usage of RAM by malloc.