Stormhawk Trusted SF Member
![Trusted SF Member Trusted SF Member](/images/ranks/globes/globes_trusted.gif)
![](images/avatars/107457045044c23a10191c0.jpg)
Joined: 26 Aug 2003 Posts: 31 Location: Warwickshire, England, UK
![Offline Offline](templates/Appalachia/images/icon_offline.gif)
|
Posted: Sat Feb 04, 2006 2:20 pm Post subject: [Column] Coding Corner 03 - Mostly Pointers |
|
|
Coding Corner 03 - Mostly Pointers
January has been a better month for the programming forum, with an increase in the number of threads, and also some interesting discussion on development issues.
Program Design
One such thread concentrated on the process of designing software, and specifically on whether pseudo-code was a design requirement, prior to writing a line of "real" code. Opinions were so divided on this topic that it was removed entirely to prevent a flame war.
I would, however, like to summarise some of that thread here. In essence, the original poster asked about designing projects, and the use of flowcharts and other design aids. Somewhere along the line, pseudo-code was introduced as one such design aid, and then other members jumped on to say that pseudo-code was essential to good program design.
I would like to point out here that pseudo-code can be thought of as "just another language", and if you're writing pseudo-code, it might as well be C, C++, Python, Perl, ASP, PHP, Visual Basic, C#, Java, etc. The main use for pseudo-code is to communicate ideas in a language independent manner, it is not specifically for designing a project prior to actually coding it, but more to allow for collaboration between developers working in different languages. As such, pseudo-code can be written after the real code, if necessary for communication purposes, and does not form a prerequisite to the coding phase of a project.
Of course, many people prefer to organise their ideas into pseudo-code first, and find it easier to program after doing so. This is not to say that they are wrong, or somehow not as good as those who launch directly into the real code, nor is it saying that those who launch directly into real code are better, or worse. The process one goes through when designing and implementing a program varies wildly from person to person, and as long as the end result is a secure, maintainable program, the path taken does not matter.
Efficient Incrementing In C / C++
https://www.security-forums.com/forum/viewtopic.php?t=37059#217152
The post linked above is in a thread about socket programming in C++, but in this particular post, capi talks of the efficiency of various ways to add one to a number in C / C++. I won't quote the post in its entirety here (that's what the link is for!) but I will say that the ++ and -- operators are there for a reason - they directly correspond to the CPU instructions to increment and decrement, found on most architectures, which will perform the operation with a greater efficiency than an addition and assignment style operation such as a = a + 1 or a += 1 (depending on optimisations made by the compiler, of course).
Inspiration For Programming Projects
https://www.security-forums.com/forum/viewtopic.php?t=37060
In this thread, the original poster asks for inspiration for some projects to engage in. My comment would have been that there are an enormous number of open-source projects out there in desperate need of additional programmers, and that a trip to Sourceforge, http://www.sourceforge.net/ , would perhaps result in the inspiration being sought, in the form of joining an open-source project and working to make something free even better!
Pointers In C
https://www.security-forums.com/forum/viewtopic.php?t=37663
https://www.security-forums.com/forum/viewtopic.php?t=37727
In these two threads, once again, the tricky topic of pointers has reared its ugly head. A pointer is a variable which holds the memory address of another variable. Stop. Go back. Read that sentence again. A pointer is a variable which holds the memory address of another variable.
In the first coding corner, I covered function pointers, and included a brief introduction to pointers in general. Here, I'll reiterate the basics of pointers in C.
A variable in C is just a bit of memory which has been allocated to store some value. For example,
The age variable is an integer, which is just 4 bytes (architecture dependant) in memory. You can refer to the integer by name, within the program, and you can also refer to it by its memory address. The & operator takes the address of a variable (or of a function, if we're talking about function pointers). Simply put, the & operator returns the memory address associated with the first byte of a variable. You can store this address in another variable, which will become a pointer to the first variable.
Code: |
int age;
age = 3;
int* a = &age;
|
Now, the value of a is the numeric memory address where the variable age can be found. The value of age is 3, as per the assignment in line 2. In order to use a pointer, one must dereference it, using the * operator. Dereferencing just means "give me the value at the memory address this pointer points to", so...
Code: |
int age;
age = 3;
int* a = &age;
if ( *a == 3 )
{
printf("Yes");
}
|
will print the string Yes, since the *a operation tells it to get the value stored at the address pointed to by a. Since the address pointed to by a is the address of age, and 3 is the value stored in age, *a is indeed equal to 3.
A pointer can be incremented, decremented (addition or subtraction of 1), as well as more general pointer arithmetic such as addition of larger numbers. In the example below, we create an array of 26 characters, and a pointer to the first character (note that an array name is a pointer to its first element). We then print each character of the array in turn, by incrementing the pointer and printing the value pointed to.
Code: |
char letters[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char* p = letters;
for(int i = 0; i < 26; i++)
{
printf("%c",*p);
p++;
}
|
Some things to note here: We can't treat the letters[] array as a C string because it does not end with a null character, '\0'. Each time through the for loop, p gets incremented. Let's pause for a minute to think about what this means.
p is a pointer to the first element of letters, because that's what we assigned it to be in the second line of code. p therefore contains the address of letters[0]. When we add one to p, we get the address of letters[1]. Adding one again gives the address of letters[2].
Now, as we go through the loop, adding 1 to p each time, we print the value of *p, a single character (since p points to a memory location which contains character data, *p is the character actually pointed to).
It is possible to use the *p construct on the left hand side of an assignment (as a so-called lvalue). The Assuming the same char letters[] array as above, the code below sets the fourth letter to be \0, then prints the string that results.
Code: |
char letters[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
char* p = letters;
p += 3; /* Now p points to the fourth letter */
*p = '\0'; /* Set the fourth letter to \0 */
printf("%s",letters);
|
The output is now
Why is this? Well we used a pointer to change the contents of the array, making the fourth letter a null character, which is a string-terminator in C. We can now treat char letters[] as a C string, which is printed using %s, up to the null character. As the null character replaced the character previously at position 4 ('d'), the characters prior to this position are interpreted by printf() as a C string, and printed out: abc.
Pointers can be used to pass data into functions, allowing the function to modify the data in the calling scope instead of just in their local scope, and can be used to index arrays. Pointers can hold the memory address of any object in memory, an integer, a float, a double, a function, a string... the pointer type defines how the increment operation actually affects the address stored. If you have an int* i; and do i++, you will add sizeof(int) to the memory address stored in i. With a char* c; c++ will add sizeof(char) to the pointer.
Finally, there exists the all-powerful void pointer, void* x; This can be used to point to anything, but is meaningless unless cast to some other type later. The void* allows a program to pass arbitrary pointers between parts of itself, so long as the program correctly knows how to reinterpret those void pointers back to some valid C type before it wants to actually use them.
As a final note on pointers, it is possible, and indeed, easy, to create a pointer with an undefined value. This will point to some random location in memory, and maybe to a position outside the address space of the program. Attempting to use an undefined pointer causes undefined results. It may crash the program, it may cause a segmentation fault, it may continue without anyone ever noticing, it may crash the operating system itself, or it may do something else entirely!
There is much more to be discussed on pointers, and they are a powerful concept which, when used correctly, can make many programming tasks easier. Expect to see more discussion on pointers in future Coding Corners, and on the programming forum itself.
PHP & SQL Security
To close this column, I'd like to draw attention to the first two parts of an article series I am writing on PHP and SQL Security. These articles introduce the security aspects of PHP and SQL based websites from the basics. The finished series will be four or five parts long (I'm still writing it!) and the first two are available from the links below.
http://www.acunetix.com/websitesecurity/php-security-1.htm
http://www.acunetix.com/websitesecurity/php-security-2.htm
|
|