IPB

Welcome Guest ( Log In | Register )



Tags
This content has not been tagged yet
 
Reply to this topicStart new topic

Tutorial: Help About C & C++ Programming Langauge


heaven_master_as...
no avatar
Newbie [Level 2]
**
Group: Members
Posts: 27
Joined: 22-August 06
From: India / Mumbai
Member No.: 28,760



Post #1 post Aug 23 2006, 02:18 PM
Help About C & C++ Programming Langauge


Prologue
I remember the time I started learning C. It was not too long ago. I liked programming, I always did, but I didn't know a lot of languages. The only languages I knew were useless, such as Visual Basic, PHP, ASP, and the basics of Javascript and VBScript.
So I decided to learn a real language: C. So I downloaded some tutorials and started reading. The well known "Hello, world!" program didn't cause any difficulties, nor did the few programs after it.

But then some new word showed up in the tutorial: "pointer". What was this horrible thing? I kept reading, but I just could not understand it. Maybe it was because my first language wasn't English, and the explenation was too hard? I didn't know - I still don't actually. Maybe my English was too bad back then?

Fortunately I didn't give up and kept on reading. I understood everything except for the pointer, and it was a huge pain in the *arse*. Pointers are used very often in C. And it took a long time before I really understood how pointers worked and yet it was actually very easy... Once you understand it. So I will try to explain it in this tutorial. Basic knowledge of C is required.
POINTERS

What is a pointer?
A pointer is nothing else than an address of some place in the memory. A pointer can be defined like:
char* test;
In this case, test is a number, not a char as you might think. It's a number - an address to be exact. This address is an address of a place in the memory.
Let's describe the memory as a bunch of lines. Every line (-) is one byte. The "^" points to a line, thus to a byte. Now have a look at the following drawing:
QUOTE
--------------------------------------------------------------------------
^

The "^" points to a byte. It just shows you one place in the memory. It's a pointer(!) to a place in the memory.

So the pointer is an address. The address may or may not already point to a valid address in the memory right after you declared it, that depends on the way you declare it:
char* test;
will NOT point to a valid address in the memory. You will have to make it point somewhere before you read/write from/to it, or else a "Segmentation Fault" will occur.

CODE
char test[10];


will point to a valid address in the memory. You can read/write from/to the memory, but be careful: you can not read/write more than 10 characters (note the [10]?). If you DO read/write more than 10 characters, a "Segmentation Fault" will occur. Of course this 10 can be changed, which will allow more characters to be read/written.
What's the use of pointers?

There are many uses of pointers. A lot of functions need pointers to be passed. One example is printf if you want to print a string: it will need a pointer to this string. Another use is the ability to use arrays. You may not know what it means now, but I will cover that later. I do assume you know what printf does and how it works. If you do not, please read the printf manual.
Point the pointer
In case you define it the first way ("char* test"), it will not yet point to a valid address in the memory. You can make it point somewhere with malloc. Malloc will reserve the specified amount of bytes and return the memory address of this.

So malloc will create a place in the memory where you can read/write from/to without any problems. It will "allocate" some space in the memory (malloc = Memory ALLOCate). The malloc function will take the ammount of space to allocate as a parameter and return the pointer to the memory. It will return a "void *", but that doesn't matter since all pointers are actually handled exactly the same. Though, there are differences in how you can read/write from/to the memory, so always use the type you want to read or write.
An example:
QUOTE
char* test;
test = (char*)malloc(10);


This will allocate 10 bytes (10 bytes, not 10 characters! The size of a character is 1 byte most of the times, but it may differ.), and assign the location of the memory to test. Note that I use "(char*)" before malloc. This will not convert anything and this is not required. Though, if you don't do this your compiler will display a warning ("warning: assignment makes pointer from integer without a cast"), and it is best to have as little warnings in your program as possible.
CODE

[indent]Malloc or [#]

So there are two ways to create a pointer to the memory to write to:
CODE
char test[10];

or
CODE
char* test;
test = (char*)malloc(10);

Of course the number 10 can be changed into any number above 0 (although there is a maximum, but you will probably never reach it).

There are two differences in these ways. The first difference is that from "char test[10];", the size can not be changed. It will keep a length of 10 characters but you can always re-allocate the space for a "char* test;". The second difference is that "char test[10];" will reserve 10 characters while malloc will reserve 10 bytes if you specify 10 as the parameter. On most machines a character will be 1 byte, but this is not on all machines. You can use "malloc(10 * sizeof(char));" to allocate 10 characters in stead of 10 bytes (sizeof(char) will return the size of one character, multiplied with the number of characters to allocate will be the memory in bytes to allocate). You should always do this so that your program will be portable to other computers.
Malloc may fail. This can for example happen when there wasn't enough memory to allocate the specified bytes. If this happens, malloc will return NULL. You should always check whether its NULL after you allocated some space. If you write to a NULL pointer, a "Segmentation Fault" will occur.
I will use "[#]" the rest of this tutorial, because that's easier. Note that the other method may be required sometimes, but since that not the case now and "[#]" will only be one line of code, I will use that method.

Free
If you have a pointer created by malloc which you will not use anymore, you should ALWAYS use free(pointer); (where pointer is the pointer). You must do this before you use malloc on the same pointer again, too. If you do not do this, your program will leak memory. This is bad if it happens once or twice, but can kill your program if it happens very often!

But there is another way to kill your program, which you should watch out for, too. You may not EVER free a pointer which either has not yet been allocated, which failed to be allocated or which has been defined with "[#]". If you do this, a "Segmentation Fault" will occur.
So to make sure you are not freeing a pointer that failed to be created, you should always add a check before you free it:
CODE
if(test != NULL)
free(test);


But if you declared test with "char* test;", test will not be NULL. So if it is not allocated and it tries to free it, the program will crash. This is why you should alway declare pointers you will malloc later with "char* test = NULL;". That way the default will be NULL, and the above check will also prevent it from freeing unallocated parts of the memory.

One more tricky part: free will not make the pointer NULL again. So if it is possible it would free it more than once, always use the following check:
CODE
if(test != NULL)
{
free(test);
test = NULL;
}

test will be set to NULL when freed, and will not be freed anymore until it has been re-allocated.

Access the memory one by one
You can access the memory on several ways. One way is to access it one by one. I can't say byte by byte, since it differs on how you declared it. For example, if you used a pointer to an integer, this will work integer by integer. If it's to a character it will work character by character.
For example, let's define it as a char:
CODE
char test[10] = "0123456789";


This will allocate the space for 10 characters (10 x sizeof(char) bytes), and put "0123456789" in the memory on that place. Test will point to the first character to this string: "0". Now lets say you have defined a character: "char test2;" and you want to put the second character of test in it. What could you do?

What we actually got is nothing else than an array of characters: 10 characters after each other. You can simply access these characters in the memory with "test[#];". Replace the "#" with the number of the character you need, minus one. In this case, "test[0]" equals "0". This way of accessing it will select a char from the memory, not a byte. So in this case, you can pick any number from 0 to 9, and test[#] (where # is your chosen number) will have your number stored as character. Make sure you do not pick a number below 0 or higher than 9, or else it will cause the program to crash with a "Segmentation Fault" or just return a character from another part of the memory.

So test[1] will be in the memory with the address test + 1 * sizeof(char). Test[#] will not return a pointer, but a char, but "test + 1 * sizeof(char)" is possible and will return a pointer. Of course, test[2] will be in the memory with the address test + 2 * sizeof(char), etc.
You can also get a character of a specified memory address by adding a "*" in front of it. For example, "char test2 = *test;" will put the character test points to in test2. Again, you can also use "char test2 = *(test + 1 * sizeof(char));", which will select the second character in the array.

So this means that
CODE
"test[0]" equals "*test",
"test[1]" equals "*(test + 1 * strlen(char));",
"test[2]" equals "*(test + 2 * strlen(char));",
and so on.

Here, too, you must pay attention: you may not read in a memory location you did not allocate. Otherwise the result will be a character of something different in the memory from or, again, cause a "Segmentation Fault".
Of course you can write to the memory the same way:
CODE
test[0] = 'a';

will put the character "a" in the memory ('' is for characters, "" is for pointers to strings), and
CODE
*test = 10;

will put a return character (\n, ascii code 10) in the memory test points to.

Value to pointer

Let's say you have a character and you would like to know where in the memory it is. It's very simple to do this: just put a "&" in front of the variable you want the pointer of, and it will return a pointer. So:

CODE
char* test;
char test2 = '!'; //This character is somewhere in the memory... but Where?
test = &test2; //Ah, there it is!


Now test contains the address of the memory where test2 is stored. This can be used on, for example, the following way:

CODE
char test[11] = "0123456789\0";
//\0 Makes sure it ends with a 0-character. If not, the printf
//function will just keep on reading until it sees a 0-char.
//So it will display characters which should not be shown.
//Or may cause a "Segmentation Fault"
printf("%s\n", &test[1]);


The first thing to explain is the term a "0-character". It's a character with the ascii code 0. In a string, it identifies the end of the string. If this is read, the functions know what the end of the string is.
test[1] will select the second character. The & will make a pointer of it. So the pointer to the second character of "0123456789" will be passed, thus the memory address of the character '1' will be passed to printf. Printf will read the memory, and show the characters there. So it will show "123456789". If test[10] would not be 0, it would keep on reading memory outside test's allocated memory, and possible show characters that should not be shown, maybe even complete passwords if you're unlucky or it may crash with a "Segmentation Fault".

Copy functions

You can use the method described above to assign values to the memory manually. Of course, this is a lot of work for some tasks. For example, if you would want to put "test" in the memory, ending with a 0 character so that you can use it with printf(); later, you could use:

CODE
char test[5];
test[0] = 't';
test[1] = 'e';
test[2] = 's';
test[3] = 't';
test[4] = 0;

Too much work. And you can't use
CODE
char test[10] = "0123456789";
test = "9876543210";


either, because that would try to put the string "9876543210" somewhere in the memory, and try to put the pointer in test. Not the string itself into the memory where the pointer points to.
For this use some functions were developed. I won't cover all of them, but I will cover the ones you will probably use most:

- sprintf and snprintf
- strcpy and strncpy
- memcpy


Note that all those functions can cause so called "buffer overflows" these are exploits that can be used for causing the program to crash, or even become (both remote or local) root, or just get a remote shell. You should NEVER try to copy more characters to the destination than allocated for the destination! Check all the data you want to write before you actually write it!
sprintf and snprintf

I said earlier in this tutorial I assume you know how printf works. That's required to understand this function too: this is simply because the sprintf function is almost identical to the printf function. Everything works exactly the same, but it will require one more paramter: the first parameter has to be the pointer pointing to the place in the memory to write to. The output will unlike the printf function not be sent to the screen, but to the memory the pointer points to. An

example:

CODE
char test[11];
sprintf(test, "%s", "0123456789");


will write "0123456789" to the memory where test points to. This string will be terminated with a 0-character so that you can pass it to functions like printf. Note you will have to spare one character for this 0-character too! But this is still unsafe.
For this matter, snprintf has been developed. This is almost identical to the sprintf function with one difference: it has one more parameter, inserted between the first and second parameter, which will be the MAXIMUM number of characters to write to the memory. This is including the 0-character, thus:

CODE
char test[10];
snprintf(test, 10, "%s", "0123456789");


Will only print "012345678" to the memory, ended with a 0-character. Note that it will not only stop when the maximum number of characters has been reached, but also when a 0-character is seen. This is because the 10th character is the last character allowed to be written and has to be changed to a 0-character in order be allowed to be passed to functions such as printf, and a lot others. If the string to write is less than the number specified, the number is just ignored. This function is to prevent data from being written to memory where it may not be written.
Both functions will return the number of characters successfuly written, the 0-character not counted. For both functions the strings written to the memory will end with a 0-character.

strcpy and strncpy

Strcpy is even easier than sprintf. Strcpy requires two parameters, both pointers. It will read all data from the memory the second parameter points to and write this to the memory the first parameter points to. It will not stop before it reaches a 0-character (it WILL copy the 0-character too), so you should be 100% sure it ends with one! An example of this function:

CODE
char test[11];
strcpy(test, "0123456789");


will copy "0123456789" to the memory test points to, including the terminating 0-character (which is added automatically, if you use "").
Strncpy will work exactly the same way, except that it allows a third parameter: the MAXIMUM number of characters to copy. It will stop when the 0-character is reached or if the maximum number of characters has been reached. This means it is possible it does not end with a 0-character.

For example:
CODE

char test[5];
strncpy(test, "0123456789", 5);


will write "01234" to the memory test points to, but it will not be terminated with a 0-character, so you may NOT pass it to functions such as printf before you checked or added the 0-character. This function is to prevent data from being written to memory where it may not be written.

memcpy
Memcpy is another function to write something to the memory. It works the same as strncpy, except that it will not terminate after a 0-character. This is useful for things other than strings. For example if you have two variables with the same structure, and you want to copy them. The first parameter is the destination, the second the source and the third the number of bytes to write (so it's the same as strncpy).

An example:

CODE
struct sockaddr test;
struct sockaddr test2;
memcpy(&test, &test2, sizeof(test2));


This will copy test2 to the memory where test is located. Test will be exactly the same as test2 after this. Sizeof(test2) characters were copied, which is the complete size. So everything.

Compare functions

Now you may need a way to compare two memory locations. For exmaple, are two strings the same, or are two memory locations the same. For this you will need to know three more functions:
- strcmp and strncmp
- memcmp


strcmp and strncmp

Strcmp is the easiest function to compare. It compares two strings (both the parameters), and it will return 0 if the strings are the same. Both strings must be terminated with a 0-character.

An example:

CODE
char test[11] = "0123456789";
char test2[11] = "9876543210";
if(strcmp(test, test2) == 0)
printf("The strings are the same (1)\n");
strcpy(test2, "0123456789");
if(strcmp(test, test2) == 0)
printf("The strings are the same (2)\n");


This will only display the string "The strings are the same (2)\n". Thus only the second time there was a match.
Strncmp is almost identical, but it will take a third parameter: the number of characters to test. It will ignore all the characters behind this.

An example:
CODE
char test[11] = "0123456789";
if(strncmp(test, "01234", 5) == 0)
printf("The first 5 characters are equal (1)!\n");
if(strncmp(test, "01234!", 6) == 0)
printf("The first 6 characters are equal (2)!\n");


This will only display the string "The first 5 characters are equal (1)!\n". Thus only the first time there was a match.

memcmp

memcmp is identical to strncmp, except that it will not be terminated by the 0-character. This is useful to compare two non-strings, for example structures. Let's take the example from memcpy a bit further:
CODE
struct sockaddr test;
struct sockaddr test2;
memcpy(&test, &test2, sizeof(test2));
if(memcmp(&test, &test2, sizeof(test2)) == 0)
printf("test equals test2\n");

This equals both test's. Since they were just copied, they are identical.

Comments
This version of this textfile is released in astalavista.net and has been written under the name of my group, the Raiders of the Lost Circuit (RLC). You can contact me (Spoofed Existence) using u2u if you got any questions, comments, etc. You can also contact me with u2u if you would like to join the Raiders of the Lost Circuit. We do not yet have a website, but we are working on it.
The Raiders of the Lost Circuit is not a hacking group. It's a group of all kind of people: we have (and still need) authors, programmers, researchers, exploits finders and lots more. If you think you are good enough for any job, even when this job isn't mentioned here, u2u me and we will talk about it.
And please, DO comment. What isn't clear (enough)? What should be improved?
Go to the top of the page
+Quote Post
sportytalk
no avatar
Super Member
*********
Group: Members
Posts: 326
Joined: 7-October 05
Member No.: 12,650



Post #2 post Aug 24 2006, 10:57 PM
Thanks for posting this information about C and C++ programming.

I was trying to learn these two languages but was finding some parts a little difficult. This topic has helped out a little bit by explaining the functions etc in more detail.

Hopefully i'll be able to go back to programming finding it a little easier now I've read this smile.gif
Go to the top of the page
+Quote Post
iGuest
no avatar
Hail Caesar!
*********************
Group: Members
Posts: 5,876
Joined: 21-September 07
Member No.: 50,369



Post #3 post Sep 12 2008, 03:13 PM
inverse of matrix
Tutorial: Help About C & C++ Programming Langauge

If we have a 40*40 matrix, then find out the time to calculate the inverse of the matrix I.E the time it will take to give the output of the given matrix.

-question by sarvesh
Go to the top of the page
+Quote Post

Reply to this topicStart new topic

Collapse

> Similar Topics

    Topic Title Replies Topic Starter Views Last Action
No New Posts   0 Albus Dumbledore 1,138 18th June 2006 - 08:28 AM
Last post by: Albus Dumbledore
No New Posts   9 noxit 874 30th July 2004 - 02:57 PM
Last post by: templest
No new   32 ultrasmad 3,934 14th February 2005 - 11:01 AM
Last post by: Someone
No new   16 ultrasmad 3,098 21st May 2005 - 10:04 AM
Last post by: alexia
No New Posts   3 ultrasmad 785 30th July 2004 - 03:27 PM
Last post by: templest
No New Posts   0 williantg 212 16th July 2004 - 08:03 PM
Last post by: williantg
No new   17 eforumhongkong 1,267 24th August 2004 - 03:13 AM
Last post by: NuHoaXuLa
No new   34 Bash 9,081 23rd February 2007 - 05:13 AM
Last post by: btdesign
No New Posts   3 Albus Dumbledore 333 20th May 2007 - 04:46 AM
Last post by: jlhaslip
No New Posts   1 dundun2007 677 23rd August 2004 - 08:06 PM
Last post by: Supaflyfrank
No New Posts   0 etycto 302 2nd September 2007 - 09:43 PM
Last post by: etycto
No New Posts   9 neeki4444 2,478 25th March 2008 - 03:19 AM
Last post by: osknockout
No New Posts   1 NeXDesigns 609 16th September 2004 - 07:46 PM
Last post by: ipunto21
No New Posts   7 NeXDesigns 620 30th September 2004 - 01:16 PM
Last post by: Amorphia
No New Posts   1 NeXDesigns 1,149 30th September 2004 - 09:28 AM
Last post by: OpaQue


 



RSS Lo-Fi Version Time is now: 5th December 2008 - 11:30 AM