Tuesday, August 31, 2010

Arrays revealed (1 d mainly) in cpp

First, there are only one-dimensional arrays in C or C++. The number of elements is put between brackets:

Expand|Select|Wrap|Line Numbers
  1. int array[5];
  2.  
That is an array of 5 elements each of which is an int.

Expand|Select|Wrap|Line Numbers
  1. int array[];
  2.  
won't compile. You need to declare the number of elements.

Enum in c++

The problem: representing series of values

It is very common to have a series of values that need to be represented. For example, to simulate a traffic light requires representing three values (red, yellow, and green), but there is no built-in C++ color datatype.

Use integer values to represent colors, for example red as 0, yellow as 1, and green as 2. There is nothing "green" about the value 2, and it could just as easily be represented by some other number. However, it is common to start a series at zero and continue up by ones.

The danger of magic numbers

Use of these "magic" numbers in the source code makes the code unreadable. For example,
x = 1;
What does this do, assign the number one or the color yellow to x?

Use of numbers is also very error prone - it is easy to mistakenly use the wrong one and making changes to the numbers and making updates to all references is difficult.

Use names instead of numbers

A better solution is to create named constants for each of the values. By convention, these named constants are uppercase.
const int RED    = 0;
const int YELLOW = 1;
const int GREEN = 2;
Now it's easy to distinguish between assignment of the number 1 and the color yellow.
int y;
int x;
. . .
y = 1; // assigns the integer one
x = YELLOW; // assigns yellow (which happens to be 1).
There is still the problem that we declare x as an int altho it's a color.

The enum type declaration provides a solution

C++ uses the enum statement to assign sequential integer values to names and provide a type name for declaration.
enum TrafficLightColor {RED, YELLOW, GREEN};
. . .
int y;
TrafficLightColor x;
. . .
y = 1;
x = YELLOW;
The enum declaration creates a new integer type. By convention the first letter of an enum type should be in uppercase. The list of values follows, where the first name is assigned zero, the second 1, etc.

Type checking prevents some erroneous assignments

The compiler may issue an error message or warning if you try to assign one kind of enum to a different kind. It also allows some dangerous types of assignments.
enum TrafficLightColor {RED, YELLOW, GREEN};
enum Gender {MALE, FEMALE};
TrafficLightColor x;
int i;
. . .
x = YELLOW; // good
i = x; // Legal, but bad style. Assigns the integer representation.
i = (int)x; // As above, explicit casting is better style.
x = (TrafficLightColor)2; // Legal, but very dangerous. No checking.

x = FEMALE; // BAD, Compiler may give error or warning.
x = 5; // BAD, Compiler may give error or warning.
 

Setting enum values

It's possible to control the values that are assigned to each enum constant. If a value is assingned to a constant, each successive constant without a value is assigned a value one greater than the previous. enum Day {MON=1, TUE, WED, THU, FRI, SAT, SUN}; The value of MON is one, TUE is two, etc instead of starting at zero. Another use of specific values is to create sets. Explicitly setting the values to powers of two represents each as separate bit. These values can then manipulated using the bit operations (&, |, ^ and ~).
enum Day {MON=1, TUE=2, WED=4, THU=8, FRI=16, SAT=32, SUN=64}; const int WEEKDAY = MON+TUE+WED+THU+FRI; . . . Day today; // This will have one of the values in it. . . . if ((today & WEEKDAY) != 0) . . .

Enum I/O

I/O of enums uses their integer values, not their names. This is not what is desired normally, so extra programming is required on input and output to use the names instead of integer values. The extra work for enum I/O means that they are often not used for simple programs.

Other languages

Java will have type-safe enums in version 1.5. Currently it requires programmers to explicitly declare each name as a constant ints. C# provides enums with additional facilities, eg to get names and check values.

The enum keyword is used to create an enumerated type named name that consists of the elements in name-list. The var-list argument is optional, and can be used to create instances of the type along with the declaration. For example, the following code creates an enumerated type for colors:
enum ColorT {red, orange, yellow, green, blue, indigo, violet};
...
ColorT c1 = indigo;
if( c1 == indigo ) {
cout << "c1 is indigo" << endl;
}
In the above example, the effect of the enumeration is to introduce several new constants named red, orange, yellow, etc. By default, these constants are assigned consecutive integer values starting at zero. You can change the values of those constants, as shown by the next example:
enum ColorT { red = 10, blue = 15, green };
...
ColorT c = green;
cout << "c is " << c << endl;
When executed, the above code will display the following output:
c is 16
Note that the above examples will only work with C++ compilers. If you're working in regular C, you will need to specify the enum keyword whenever you create an instance of an enumerated type:
enum ColorT { red = 10, blue = 15, green };
...
enum ColorT c = green; /* note the additional enum keyword */
printf( "c is %d\n", c );
Alternatively, add a typedef to bring C and C++ on par:
typedef enum ColorT { red = 10, blue = 15, green } ColorT;
...
ColorT c = green; /* no more additional enum keyword */
printf( "c is %d\n", c );

 

Common errors in c

1. Introduction

This document lists the common C programming errors that the author sees time and time again. Solutions to the errors are also presented.

2. Beginner Errors

These are errors that beginning C students often make. However, the professionals still sometimes make them too!
  • Forgetting to put a break in a switch statement

Remember that C does not break out of a switch statement if a case is encountered. For example:

int x = 2;
switch(x) {
case 2:
printf("Two\n");
case 3:
printf("Three\n");
}

prints out:

Two
Three

Put a break to break out of the switch:

int x = 2;
switch(x) {
case 2:
printf("Two\n");
break;
case 3:
printf("Three\n");
break; /* not necessary, but good if additional cases are added later */
}

  • Using = instead of ==

C's = operator is used exclusively for assignment and returns the value assigned. The == operator is used exclusively for comparison and returns an integer value (0 for false, not 0 for true). Because of these return values, the C compiler often does not flag an error when = is used when one really wanted an ==. For example:

int x = 5;
if ( x = 6 )
printf("x equals 6\n");

This code prints out x equals 6! Why? The assignment inside the if sets x to 6 and returns the value 6 to the if. Since 6 is not 0, this is interpreted as true.


Avoiding this error -
One way to have the compiler find this type of error is to put any constants (or any r-value expressions) on the left side. Then if an = is used, it will be an error:
if ( 6 = x)

  • scanf() errors

There are two types of common scanf() errors:
2.3.1 Forgetting to put an ampersand (&) on arguments

scanf() must have the address of the variable to store input into. This means that often the ampersand address operator is required to compute the addresses. Here's an example:

int x;
char * st = malloc(31);

scanf("%d", &x); /* & required to pass address to scanf() */
scanf("%30s", st); /* NO & here, st itself points to variable! */

As the last line above shows, sometimes no ampersand is correct!
2.3.2 Using the wrong format for operand

C compilers do not check that the correct format is used for arguments of a scanf() call. The most common errors are using the %f format for doubles (which must use the %lf format) and mixing up %c and %s for characters and strings.

  • Size of arrays

Arrays in C always start at index 0. This means that an array of 10 integers defined as:

int a[10];

has valid indices from 0 to 9 not 10! It is very common for students go one too far in an array. This can lead to unpredictable behavior of the program.
2.5 Integer division

Unlike Pascal, C uses the / operator for both real and integer division. It is important to understand how C determines which it will do. If both operands are of an integal type, integer division is used, else real division is used. For example:

double half = 1/2;

This code sets half to 0 not 0.5! Why? Because 1 and 2 are integer constants. To fix this, change at least one of them to a real constant.

double half = 1.0/2;

If both operands are integer variables and real division is desired, cast one of the variables to double (or float).

int x = 5, y = 2;
double d = ((double) x)/y;

2.6 Loop errors

In C, a loop repeats the very next statement after the loop statement. The code:

int x = 5;
while( x > 0 );
x--;

is an infinite loop. Why? The semicolon after the while defines the statement to repeat as the null statement (which does nothing). Remove the semicolon and the loop works as expected.

Another common loop error is to iterate one too many times or one too few. Check loop conditions carefully!
2.7 Not using prototypes

Prototypes tell the compiler important features of a function: the return type and the parameters of the function. If no prototype is given, the compiler assumes that the function returns an int and can take any number of parameters of any type.

One important reason to use prototypes is to let the compiler check for errors in the argument lists of function calls. However, a prototype must be used if the function does not return an int. For example, the sqrt() function returns a double, not an int. The following code:

double x = sqrt(2);

will not work correctly if a prototype:

double sqrt(double);

does not appear above it. Why? Without a prototype, the C compiler assumes that sqrt() returns an int. Since the returned value is stored in a double variable, the compiler inserts code to convert the value to a double. This conversion is not needed and will result in the wrong value.

The solution to this problem is to include the correct C header file that contains the sqrt() prototype, math.h. For functions you write, you must either place the prototype at the top of the source file or create a header file and include it.
2.8 Not initializing pointers

Anytime you use a pointer, you should be able to answer the question: What variable does this point to? If you can not answer this question, it is likely it doesn't point to any variable. This type of error will often result in a Segmentation fault/coredump error on UNIX/Linux or a general protection fault under Windows. (Under good old DOS (ugh!), anything could happen!)

Here's an example of this type of error.

#include
int main()
{
char * st; /* defines a pointer to a char or char array */

strcpy(st, "abc"); /* what char array does st point to?? */
return 0;
}

How to do this correctly? Either use an array or dynamically allocate an array.

#include
int main()
{
char st[20]; /* defines an char array */

strcpy(st, "abc"); /* st points to char array */
return 0;
}

or

#include
#include
int main()
{
char *st = malloc(20); /* st points to allocated array*/

strcpy(st, "abc"); /* st points to char array */
free(st); /* don't forget to deallocate when done! */
return 0;
}

Actually, the first solution is much preferred for what this code does. Why? Dynamical allocation should only be used when it is required. It is slower and more error prone than just defining a normal array.
3. String Errors
3.1 Confusing character and string constants

C considers character and string constants as very different things. Character constants are enclosed in single quotes and string constants are enclosed in double quotes. String constants act as a pointer to the actually string. Consider the following code:

char ch = 'A'; /* correct */
char ch = "A"; /* error */

The second line assigns the character variable ch to the address of a string constant. This should generate a compiler error. The same should happen if a string pointer is assigned to a character constant:

const char * st = "A"; /* correct */
const char * st = 'A'; /* error */

3.2 Comparing strings with ==

Never use the == operator to compare the value of strings! Strings are char arrays. The name of a char array acts like a pointer to the string (just like other types of arrays in C). So what? Consider the following code:

char st1[] = "abc";
char st2[] = "abc";
if ( st1 == st2 )
printf("Yes");
else
printf("No");

This code prints out No. Why? Because the == operator is comparing the pointer values of st1 and st2, not the data pointed to by them. The correct way to compare string values is to use the strcmp() library function. (Be sure to include string.h) If the if statement above is replaced with the following:

if ( strcmp(st1,st2) == 0 )
printf("Yes");
else
printf("No");

the code will print out Yes. For similar reasons, don't use the other relational operators (<,>, etc.) with strings either. Use strcmp() here too.
3.3 Not null terminating strings

C assumes that a string is a character array with a terminating null character. This null character has ASCII value 0 and can be represented as just 0 or '\0'. This value is used to mark the end of meaningful data in the string. If this value is missing, many C string functions will keep processing data past the end of the meaningful data and often past the end of the character array itself until it happens to find a zero byte in memory!

Most C library string functions that create strings will always properly null terminate them. Some do not (e.g., strncpy() ). Be sure to read their descriptions carefully.
3.4 Not leaving room for the null terminator

A C string must have a null terminator at the end of the meaningful data in the string. A common mistake is to not allocate room for this extra character. For example, the string defined below

char str[30];

only has room for only 29 (not 30) actually data characters, since a null must appear after the last data character.

This can also be a problem with dynamic allocation. Below is the correct way to allocate a string to the exact size needed to hold a copy of another.

char * copy_str = malloc( strlen(orig_str) + 1);
strcpy(copy_str, orig_str);

The common mistake is to forget to add one to the return value of strlen(). The strlen() function returns a count of the data characters which does not include the null terminator.

This type of error can be very hard to detect. It might not cause any problems or only problems in extreme cases. In the case of dynamic allocation, it might corrupt the heap (the area of the program's memory used for dynamic allocation) and cause the next heap operation (malloc(), free(), etc.) to fail.
4. Input/Output Errors
4.1 Using fgetc(), etc. incorrectly

The fgetc(), getc() and getchar() functions all return back an integer value. For example, the prototype of fgetc() is:

int fgetc( FILE * );

Sometimes this integer value is really a simple character, but there is one very important case where the return value is not a character!

What is this value? EOF A common misconception of students is that files have a special EOF character at the end. There is no special character stored at the end of a file. EOF is an integer error code returned by a function. Here is the wrong way to use fgetc():

int count_line_size( FILE * fp )
{
char ch;
int cnt = 0;

while( (ch = fgetc(fp)) != EOF && ch != '\n')
cnt++;
return cnt;
}

What is wrong with this? The problem occurs in the condition of the while loop. To illustrate, here is the loop rewritten to show what C will do behind the scenes.

while( (int) ( ch = (char) fgetc(fp) ) != EOF && ch != '\n')
cnt++;

The return value of fgetc(fp) is cast to char to store the result into ch. Then the value of ch must be cast back to an int to compare it with EOF. So what? Casting an int value to a char and then back to an int may not give back the original int value. This means in the example above that if fgetc() returns back the EOF value, the casting may change the value so that the comparison later with EOF would be false.

What is the solution? Make the ch variable an int as below:

int count_line_size( FILE * fp )
{
int ch;
int cnt = 0;

while( (ch = fgetc(fp)) != EOF && ch != '\n')
cnt++;
return cnt;
}

Now the only hidden cast is in the second comparison.

while( (ch = fgetc(fp)) != EOF && ch != ((int) '\n') )
cnt++;

This cast has no harmful effects at all! So, the moral of all this is: always use an int variable to store the result of the fgetc(), getc() and getchar().
4.2 Using feof() incorrectly

There is a wide spread misunderstanding of how C's feof() function works. Many programmers use it like Pascal's eof() function. However, C's function works differently!

What's the difference? Pascal's function returns true if the next read will fail because of end of file. C's function returns true if the last function failed. Here's an example of a misuse of feof():

#include
int main()
{
FILE * fp = fopen("test.txt", "r");
char line[100];

while( ! feof(fp) ) {
fgets(line, sizeof(line), fp);
fputs(line, stdout);
}
fclose(fp);
return 0;
}

This program will print out the last line of the input file twice. Why? After the last line is read in and printed out, feof() will still return 0 (false) and the loop will continue. The next fgets() fails and so the line variable holding the contents of the last line is not changed and is printed out again. After this, feof() will return true (since fgets() failed) and the loop ends.

How should this fixed? One way is the following:

#include
int main()
{
FILE * fp = fopen("test.txt", "r");
char line[100];

while( 1 ) {
fgets(line, sizeof(line), fp);
if ( feof(fp) ) /* check for EOF right after fgets() */
break;
fputs(line, stdout);
}
fclose(fp);
return 0;
}

However, this is not the best way. There is really no reason to use feof() at all. C input functions return values that can be used to check for EOF. For example, fgets returns the NULL pointer on EOF. Here's a better version of the program:

#include
int main()
{
FILE * fp = fopen("test.txt", "r");
char line[100];

while( fgets(line, sizeof(line), fp) != NULL )
fputs(line, stdout);
fclose(fp);
return 0;
}

The author has yet to see any student use the feof() function correctly!

Incidently, this discussion also applies to C++ and Java. The eof() method of an istream works just like C's feof().
4.3 Leaving characters in the input buffer


C input (and output) functions buffer data. Buffering stores data in memory and only reads (or writes) the data from (or to) I/O devices when needed. Reading and writing data in big chunks is much more efficient than a byte (or character) at a time. Often the buffering has no effect on programming.

One place where buffering is visible is input using scanf(). The keyboard is usually line buffered. This means that each line input is stored in a buffer. Problems can arise when a program does not process all the data in a line, before it wants to process the next line of input. For example, consider the following code:

int x;
char st[31];

printf("Enter an integer: ");
scanf("%d", &x);
printf("Enter a line of text: ");
fgets(st, 31, stdin);

The fgets() will not read the line of text that is typed in. Instead, it will probably just read an empty line. In fact, the program will not even wait for an input for the fgets() call. Why? The scanf() call reads the characters needed that represent the integer number read in, but it leaves the '\n' in the input buffer. The fgets() then starts reading data from the input buffer. It finds a '\n' and stops without needing any additional keyboard input.

What's the solution? One simple method is to read and dump all the characters from the input buffer until a '\n' after the scanf() call. Since this is something that might be used in lots of places, it makes sense to make this a function. Here is a function that does just this:

/* function dump_line
* This function reads and dumps any remaining characters on the current input
* line of a file.
* Parameter:
* fp - pointer to a FILE to read characters from
* Precondition:
* fp points to a open file
* Postcondition:
* the file referenced by fp is positioned at the end of the next line
* or the end of the file.
*/
void dump_line( FILE * fp )
{
int ch;

while( (ch = fgetc(fp)) != EOF && ch != '\n' )
/* null body */;
}

Here is the code above fixed by using the above function:

int x;
char st[31];

printf("Enter an integer: ");
scanf("%d", &x);
dump_line(stdin);
printf("Enter a line of text: ");
fgets(st, 31, stdin);

One incorrect solution is to use the following:

fflush(stdin);

This will compile but its behavior is undefined by the ANSI C standard. The fflush() function is only meant to be used on streams open for output, not input. This method does seem to work with some C compilers, but is completely unportable! Thus, it should not be used.
4.4 Using the gets() function

Do not use this function! It does not know how many characters can be safely stored in the string passed to it. Thus, if too many are read, memory will be corrupted. Many security bugs that have been exploited on the Internet use this fact! Use the fgets() function instead (and read from stdin). But remember that unlike gets(), fgets() does not discard a terminating \n from the input.

The scanf() functions can also be used dangerously. The %s format can overwrite the destination string. However, it can be used safely by specifying a width. For example, the format %20s will not read more than 20 characters.
5. Acknowlegements

The author would like to thank Stefan Ledent for suggesting the section on "Not leaving room for the null terminator"

The Syntax of C and C++ Function Pointers

1  Define a Function Pointer

Regarding their syntax, there are two different types of function pointers:
On the one hand there are pointers to ordinary C functions or to static C++ member functions. On the other hand there are pointers to non-static C++ member functions. The basic difference is that all pointers to non-static member functions need a hidden argument: The this-pointer to an instance of the class.
Always keep in mind: These two types of function pointers are incompatible with each other.
Since a function pointer is nothing else than a variable, it must be defined as usual. In the following example we define three function pointers named pt2Function, pt2Member and pt2ConstMember. They point to functions, which take one float and two char and return an int. In the C++ example it is assumed, that the functions, our pointers point to, are (non-static) member functions of TMyClass.


// 2.1 define a function pointer and initialize to NULL
int (*pt2Function)(float, char, char) = NULL; // C
int (TMyClass::*pt2Member)(float, char, char) = NULL; // C++
int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL; // C++

2.2  Calling Convention

Normally you don't have to think about a function's calling convention: The compiler assumes __cdecl as default if you don't specify another convention. However if you want to know more, keep on reading ... The calling convention tells the compiler things like how to pass the arguments or how to generate the name of a function. Some examples for other calling conventions are __stdcall, __pascal and __fastcall. The calling convention belongs to a function's signature: Thus functions and function pointers with different calling convention are incompatible with each other! For Borland and Microsoft compilers you specify a specific calling convention between the return type and the function's or function pointer's name. For the GNU GCC you use the __attribute__ keyword: Write the function definition followed by the keyword __attribute__ and then state the calling convention in double parentheses. And if you want to know how function calls work under the hood you should take a look at the chapter Subprograms in Paul Carter's PC Assembly Tutorial.

// 2.2 define the calling convention
void __cdecl DoIt(float a, char b, char c); // Borland and Microsoft
void DoIt(float a, char b, char c) __attribute__((cdecl)); // GNU GCC
 

2.3  Assign an address to a Function Pointer

It's quite easy to assign the address of a function to a function pointer. You simply take the name of a suitable and known function or member function. Although it's optional for most compilers you should use the address operator & infront of the function's name in order to write portable code. You may have got to use the complete name of the member function including class-name and scope-operator (::). Also you have got to ensure, that you are allowed to access the function right in scope where your assignment stands.

// 2.3 assign an address to the function pointer
// Note: Although you may ommit the address operator on most compilers
// you should always use the correct way in order to write portable code.


// C
int DoIt (float a, char b, char c){ printf("DoIt\n"); return a+b+c; }
int DoMore(float a, char b, char c)const{ printf("DoMore\n"); return a-b+c; }

pt2Function = DoIt; // short form
pt2Function = &DoMore; // correct assignment using address operator


// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };

/* more of TMyClass */
};

pt2ConstMember = &TMyClass::DoMore; // correct assignment using address operator
pt2Member = &TMyClass::DoIt; // note: may also legally point to &DoMore

 

2.4  Comparing Function Pointers

You can use the comparison-operators (==, !=) the same way as usual. In the following example it is checked, whether pt2Function and pt2Member actually contain the address of the functions DoIt and TMyClass::DoMore. A text is shown in case of equality.

// 2.4 comparing function pointers

// C
if(pt2Function >0){ // check if initialized
if(pt2Function == &DoIt)
printf("Pointer points to DoIt\n"); }
else
printf("Pointer not initialized!!\n");


// C++
if(pt2ConstMember == &TMyClass::DoMore)
cout << "Pointer points to TMyClass::DoMore" << endl;

 

2.5  Calling a Function using a Function Pointer

In C you call a function using a function pointer by explicitly dereferencing it using the * operator. Alternatively you may also just use the function pointer's instead of the funtion's name. In C++ the two operators .* resp. ->* are used together with an instance of a class in order to call one of their (non-static) member functions. If the call takes place within another member function you may use the this-pointer.

// 2.5 calling a function using a function pointer
int result1 = pt2Function (12, 'a', 'b'); // C short way
int result2 = (*pt2Function) (12, 'a', 'b'); // C

TMyClass instance1;
int result3 = (instance1.*pt2Member)(12, 'a', 'b'); // C++
int result4 = (*this.*pt2Member)(12, 'a', 'b'); // C++ if this-pointer can be used

TMyClass* instance2 = new TMyClass;
int result4 = (instance2->*pt2Member)(12, 'a', 'b'); // C++, instance2 is a pointer
delete instance2;

 

2.6  How to Pass a Function Pointer as an Argument ?

You can pass a function pointer as a function's calling argument. You need this for example if you want to pass a pointer to a callback function. The following code shows how to pass a pointer to a function which returns an int and takes a float and two char:

//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer


// is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(float, char, char))
{
int result = (*pt2Func)(12, 'a', 'b'); // call using function pointer
cout << result << endl;
}

// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
void Pass_A_Function_Pointer()
{
cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
PassPtr(&DoIt);
}

 

2.7  How to Return a Function Pointer ?

It's a little bit tricky but a function pointer can be a function's return value. In the following example there are two solutions of how to return a pointer to a function which is taking two float arguments and returns a float. If you want to return a pointer to a member function you have just got to change the definitions/declarations of all function pointers.

//------------------------------------------------------------------------------------
// 2.7 How to Return a Function Pointer
// 'Plus' and 'Minus' are defined above. They return a float and take two float



// Direct solution: Function takes a char and returns a pointer to a
// function which is taking two floats and returns a float.
// specifies which function to return

float (*GetPtr1(const char opCode))(float, float)
{
if(opCode == '+')
return &Plus;
else
return
&Minus; // default if invalid operator was passed
}


// Solution using a typedef: Define a pointer to a function which is taking
// two floats and returns a float

typedef float(*pt2Func)(float, float);

// Function takes a char and returns a function pointer which is defined
// with the typedef above. specifies which function to return

pt2Func GetPtr2(const char opCode)
{
if(opCode == '+')
return &Plus;
else
return
&Minus; // default if invalid operator was passed
}


// Execute example code
void Return_A_Function_Pointer()
{
cout << endl << "Executing 'Return_A_Function_Pointer'" << endl;

// define a function pointer and initialize it to NULL
float (*pt2Function)(float, float) = NULL;

pt2Function=GetPtr1('+'); // get function pointer from function 'GetPtr1'
cout << (*pt2Function)(2, 4) << endl; // call function using the pointer


pt2Function=GetPtr2('-'); // get function pointer from function 'GetPtr2'
cout << (*pt2Function)(2, 4) << endl; // call function using the pointer
}

 

2.8  How to Use Arrays of Function Pointers ?

Operating with arrays of function pointers is very interesting. This offers the possibility to select a function using an index. The syntax appears difficult, which frequently leads to confusion. Below you find two ways of how to define and use an array of function pointers in C and C++. The first way uses a typedef, the second way directly defines the array. It's up to you which way you prefer.
//------------------------------------------------------------------------------------
// 2.8 How to Use Arrays of Function Pointers


// C ---------------------------------------------------------------------------------

// type-definition: 'pt2Function' now can be used as type
typedef int (*pt2Function)(float, char, char);

// illustrate how to work with an array of function pointers
void Array_Of_Function_Pointers()
{
printf("\nExecuting 'Array_Of_Function_Pointers'\n");

// define arrays and ini each element to NULL, and are arrays
// with 10 pointers to functions which return an int and take a float and two char


// first way using the typedef
pt2Function funcArr1[10] = {NULL};

// 2nd way directly defining the array
int (*funcArr2[10])(float, char, char) = {NULL};


// assign the function's address - 'DoIt' and 'DoMore' are suitable functions
// like defined above in 2.1-4

funcArr1[0] = funcArr2[1] = &DoIt;
funcArr1[1] = funcArr2[0] = &DoMore;

/* more assignments */

// calling a function using an index to address the function pointer
printf("%d\n", funcArr1[1](12, 'a', 'b')); // short form
printf("%d\n", (*funcArr1[0])(12, 'a', 'b')); // "correct" way of calling
printf("%d\n", (*funcArr2[1])(56, 'a', 'b'));
printf("%d\n", (*funcArr2[0])(34, 'a', 'b'));
}


// C++ -------------------------------------------------------------------------------

// type-definition: 'pt2Member' now can be used as type
typedef int (TMyClass::*pt2Member)(float, char, char);

// illustrate how to work with an array of member function pointers
void Array_Of_Member_Function_Pointers()
{
cout << endl << "Executing 'Array_Of_Member_Function_Pointers'" << endl;

// define arrays and ini each element to NULL, and are
// arrays with 10 pointers to member functions which return an int and take
// a float and two char


// first way using the typedef
pt2Member funcArr1[10] = {NULL};

// 2nd way of directly defining the array
int (TMyClass::*funcArr2[10])(float, char, char) = {NULL};


// assign the function's address - 'DoIt' and 'DoMore' are suitable member
// functions of class TMyClass like defined above in 2.1-4

funcArr1[0] = funcArr2nd use an array of function pointers in C and C++. The first way uses a typedef, the second way directly defines the array. It's up to you which way you prefer.

[1] = &TMyClass::DoIt;
funcArr1[1] = funcArr2[0] = &TMyClass::DoMore;
/* more assignments */

// calling a function using an index to address the member function pointer
// note: an instance of TMyClass is needed to call the member functions

TMyClass instance;
cout << (instance.*funcArr1[1])(12, 'a', 'b') << endl;
cout << (instance.*funcArr1[0])(12, 'a', 'b') << endl;
cout << (instance.*funcArr2[1])(34, 'a', 'b') << endl;
cout << (instance.*funcArr2[0])(89, 'a', 'b') << endl;
}

Introduction to Pointer to function in c/cpp

Function Pointers provide some extremely interesting, efficient and elegant programming techniques. You can use them to replace switch/if-statements, to realize your own late-binding or to implement callbacks. Unfortunately - probably due to their complicated syntax - they are treated quite stepmotherly in most computer books and documentations. If at all, they are addressed quite briefly and superficially. They are less error prone than normal pointers cause you will never allocate or deallocate memory with them. All you've got to do is to understand what they are and to learn their syntax. But keep in mind: Always ask yourself if you really need a function pointer. It's nice to realize one's own late-binding but to use the existing structures of C++ may make your code more readable and clear. One aspect in the case of late-binding is runtime: If you call a virtual function, your program has got to determine which one has got to be called. It does this using a V-Table containing all the possible functions. This costs some time each call and maybe you can save some time using function pointers instead of virtual functions.

What is a Function Pointer?

Function Pointers are pointers, i.e. variables, which point to the address of a function. You must keep in mind, that a running program gets a certain space in the main-memory. Both, the executable compiled program code and the used variables, are put inside this memory. Thus a function in the program code is, like e.g. a character field, nothing else than an address. It is only important how you, or better your compiler/processor, interpret the memory a pointer points to.

Introductory Example or How to Replace a Switch-Statement

Switch case uses jump-tables, therefore we keep ourself to int as cases, viewing it from efficiency point of view. We will see how it works here.
When you want to call a function DoIt() at a certain point called label in your program, you just put the call of the function DoIt() at the point label in your source code. Then you compile your code and every time your program comes up to the point label, your function is called. Everything is ok. But what can you do, if you don't know at build-time which function has got to be called? What do you do, when you want to decide it at runtime? Maybe you want to use a so called Callback-Function or you want to select one function out of a pool of possible functions. However you can also solve the latter problem using a switch-statement, where you call the functions just like you want it, in the different branches. But there's still another way: Use a function pointer!
In the following example we regard the task to perform one of the four basic arithmetic operations. The task is first solved using a switch-statement. Then it is shown, how the same can be done using a function pointer. It's only an example and the task is so easy that I suppose nobody will ever use a function pointer for it ;-)

//------------------------------------------------------------------------------------
// 1.2 Introductory Example or How to Replace a Switch-Statement
// Task: Perform one of the four basic arithmetic operations specified by the
// characters '+', '-', '*' or '/'.



// The four arithmetic operations ... one of these functions is selected
// at runtime with a swicth or a function pointer

float Plus (float a, float b) { return a+b; }
float Minus (float a, float b) { return a-b; }
float Multiply(float a, float b) { return a*b; }
float Divide (float a, float b) { return a/b; }


// Solution with a switch-statement - specifies which operation to execute
void Switch(float a, float b, char opCode)
{
float result;

// execute operation
switch(opCode)
{
case '+' : result = Plus (a, b); break;
case '-' : result = Minus (a, b); break;
case '*' : result = Multiply (a, b); break;
case '/' : result = Divide (a, b); break;
}

cout << "Switch: 2+5=" << result << endl; // display result
}


// Solution with a function pointer - is a function pointer and points to
// a function which takes two floats and returns a float. The function pointer
// "specifies" which operation shall be executed.

void Switch_With_Function_Pointer(float a, float b, float (*pt2Func)(float, float))
{
float result = pt2Func(a, b); // call using function pointer

cout << "Switch replaced by function pointer: 2-5="; // display result
cout << result << endl;
}


// Execute example code
void Replace_A_Switch()
{
cout << endl << "Executing function 'Replace_A_Switch'" << endl;

Switch(2, 5, /* '+' specifies function 'Plus' to be executed */ '+');
Switch_With_Function_Pointer(2, 5, /* pointer to function 'Minus' */ &Minus);
}


 mportant note: A function pointer always points to a function with a specific signature! Thus all functions, you want to use with the same function pointer, must have the same parameters and return-type!

Use the variable closer to its use

Its good programming practice to define the variable closer to its use.
Eg. In cpp, this is better code:
for(int i = 0; i{...}

rather than
int i;
...
...
for(i=0;i

How to bound check arrays in cpp / c

Bound checking in cpp /c is headache....
char *strcpy(char *dest, const char *src)
{
char *save = dest;
while(*dest++ = *src++);
return save;
}

//main func
char *src = "hello to c programming language";
char dest[12];

strcpy(dest,src); //calling function

Here we have no bound check on dest size or src size. When we pass it to function it is perfectly alright but
problem is dest is array which is just 12 bytes long...but src is larger string...

So if programmer is lucky , he gets Error - "Segmentation fault"
else in worse case, he gets his core dumped...that is his memory may have changed the effect of it can be seen after few days.

What's the solution?
We cant change this library function to check bound check, like sending size to it with both src and dest...because many programs might be using it...and this change may hamper these million of programs. So it is the responsibility of programmer to check whether he has provided enough space or not?
Note: There is no way right now to check bounds by [] operator.

Vectors
A vector will do bounds checking if you use the at() function, for example:
std::vector v(5);
v
.at(3) = 10;
v
.at(5) = 20; // throws an exception, std::out_of_range
However, if you use operator[], there is no bounds checking. (And accessing non-existent elements leads to undefined behavior.)

++ / -- and pointers operator *

++ is executed first comparing with *.

So we have to use ++ (*p)

Eg, consider strcpy() function.


char *strcpy(char *dest, const char *src)
{
char *save = dest;
while(*dest++ = *src++);
return save;
}
So here first thing that is happening in while loop is dest and src are incremented by 1
Than they are referenced by *
Then equated and finally loop moves on until it gets '\0'..i.e null

Monday, August 30, 2010

File IO in c++ 1

Introduction
This tutorial will start with the very basis of File I/O (Input/Output) in C++. After that, I will look into aspects that are more advanced, showing you some tricks, and describing useful functions.
You need to have good understanding of C++, otherwise this tutorial will be unfamiliar and not useful to you!
Your Very First Program
I will first write the code, and after that, I will explain it line by line.
The first program, will create a file, and put some text into it.
#include < fstream >
using namespace std;

int main()
{
ofstream SaveFile("cpp-home.txt");
SaveFile << "Hello World, from www.cpp-home.com!";
SaveFile.close();
return 0;
}
Only that? Yes! This program will create the file cpp-home.txt in the directory from where you are executing it, and will put “Hello World, from www.cpp-home.com!” into it.
Here is what every line means:
#include - You need to include this file in order to use C++’s functions for File I/O.
In this file, are declared several classes, including ifstream, ofstream and fstream, which are all derived from istream and ostream.
ofstream SaveFile("cpp-home.txt");
1) ofstream means “output file stream”. It creates a handle for a stream to write in a file.
2) SaveFile – that’s the name of the handle. You can pick whatever you want!
3) (”cpp-home.txt”); - opens the file cpp-home.txt, which should be placed in the directory from where you execute the program. If such a file does not exists, it will be created for you, so you don’t need to worry about that!
Now, let’s look a bit deeper. First, I’d like to mention that ofstream is a class. So, ofstream SaveFile(”cpp-home.txt”); creates an object from this class. What we pass in the brackets, as parameter, is actually what we pass to the constructor. It is the name of the file. So, to summarize: we create an object from class ofstream, and we pass the name of the file we want to create, as an argument to the class’ constructor. There are other things, too, that we can pass, but I will look into that, later.
SaveFile << "Hello World, from www.cpp-home.com"; - “<<" looks familiar? Yes, you’ve seen it in cout <<. This ("<<") is a predefined operator. Anyway, what this line makes, is to put the text above in the file. As mentioned before, SaveFile is a handle to the opened file stream. So, we write the handle name, << and after it we write the text in inverted commas. If we want to pass variables instead of text in inverted commas, just pass it as a regular use of the cout <<. This way:
SaveFile << variablename;
That’s it!
SaveFile.close(); - As we have opened the stream, when we finish using it, we have to close it. SaveFile is an object from class ofstream, and this class (ofstream) has a function that closes the stream. That is the close() function. So, we just write the name of the handle, dot and close(), in order to close the file stream!
Notice: Once you have closed the file, you can’t access it anymore, until you open it again.
That’s the simplest program, to write in a file. It’s really easy! But as you will see later in this tutorial, there are more things to learn!
Reading A File
You saw how to write into a file. Now, when we have cpp-home.txt, we will read it, and display it on the screen.
First, I’d like to mention, that there are several ways to read a file. I will tell you about all of them (all I know) later. For now, I will show you the best way (in my mind).
As you are used already - I will first write the code, and after that, I will comment it in details.
#include

void main() //the program starts here
{
ifstream OpenFile("cpp-home.txt");
char ch;
while(!OpenFile.eof())
{
OpenFile.get(ch);
cout << ch;
}
OpenFile.close();
}

You should already know what the first line is. So, let me explain you the rest.
ifstream OpenFile("cpp-home.txt") – I suppose this seems a bit more familiar to you, already! ifstream means “input file stream”. In the previous program, it was ofstream, which means “output file stream”. The previous program is to write a file, that’s why it was “output”. But this program is to read from a file, that’s why it is “input”. The rest of the code on this line, should be familiar to you. OpenFile is the object from class ifstream, which will handle the input file stream. And in the inverted commas, is the name of the file to open.
Notice that that there is no check whether the file exists! I will show you how to check that, later!
char ch; - Declares an array of type char. Just to remind you- such arrays can hold just one sign from the ASCII table.
while(!OpenFile.eof()) – The function eof() returns a nonzero value if the end of the file has been reached. So, we make a while loop, that will loop until we reach the end of the file. So, we will get through the whole file, so that we can read it!
OpenFile.get(ch); - OpenFile is the object from class ifstream. This class declares a function called get(). So, we can use this function, as long as we have an object. The get() function extracts a single character from the stream and returns it. In this example, the get() function takes just one parameter- the variable name, where to put the read character. So, after calling OpenFile.get(ch) it will read one character from the stream OpenFile, and will put this character into the variable ch.
Notice: If you call this function for a second time, it will read the next character, but not the same one! You will learn why this happens, later.
That’s why, we loop until we reach the end of the file! And every time we loop, we read one character and put it into ch.
cout << ch; - Display ch, which has the read character.
File.close(); - As we have opened the file stream, we need to close it. Use the close() function, to close it! Just as in the previous program!
Notice: Once you have closed the file, you can’t access it anymore, until you open it again.
That’s all! I hope you understood my comments! When you compile and run this program, it should output:
“Hello World, from www.cpp-home.com!”
Managing I/O streams
In this chapter, I will mention about some useful functions. I will also show you how to open file to read and write in the same time. I will show you, also, other ways to open a file; how to check if opening was successful or not. So- read on!
So far, I have showed to you, just one way to open a file, either for reading, either for writing. But it can be opened another way, too! So far, you should be aware of this method:
ifstream OpenFile("cpp-home.txt");
Well, this is not the only way! As mentioned before, the above code creates an object from class ifstream, and passes the name of the file to be opened to its constructor. But in fact, there are several overloaded constructors, which can take more than one parameter. Also, there is function open() that can do the same job. Here is an example of the above code, but using the open() function:
ifstream OpenFile;
OpenFile.open("cpp-home.txt");

What is the difference you ask? Well, I made several tests, and found no difference! Just if you want to create a file handle, but don’t want to specify the file name immediately, you can specify it later with the function open(). And by the way, other use of open() is for example if you open a file, then close it, and using the same file handle open another file. This way, you will need the open() function.
Consider the following code example:
#include

void read (ifstream &T) //pass the file stream to the function
{
//the method to read a file, that I showed you before
char ch;
while(!T.eof())
{
T.get(ch);
cout << ch;
}
cout << endl << "--------" << endl;
}


void main()
{
ifstream T("file1.txt");
read(T);
T.close();
T.open("file2.txt");
read(T);
T.close();
}

So, as long as file1.txt and file2.txt exists and has some text into, you will see it!
Now, it’s time to show you that the file name is not the only parameter that you can pass to the open() function or the constructor (it’s the same). Here is a prototype:
ifstream OpenFile(char *filename, int open_mode);
You should know that filename is the name of the file (a string). The new here is the open mode. The value of open_mode defines how to be opened the file. Here is a table of the open modes:
Name Description
ios::inOpen file to read
ios::outOpen file to write
ios::appAll the date you write, is put at the end of the file. It calls ios::out
ios::ateAll the date you write, is put at the end of the file. It does not call ios::out
ios::truncDeletes all previous content in the file. (empties the file)
ios::nocreateIf the file does not exists, opening it with the open() function gets impossible.
ios::noreplaceIf the file exists, trying to open it with the open() function, returns an error.
ios::binaryOpens the file in binary mode.
In fact, all these values are int constants from an enumerated type. But for making your life easier, you can use them as you see them in the table.
Here is an example on how to use the open modes:
#include

void main()
{
ofstream SaveFile("file1.txt", ios::ate);
SaveFile << "That's new!\n";
SaveFile.close();
}

As you see in the table, using ios::ate will write at the end of the file. If I didn’t use it, the file will be overwritten, but as I use it, I just add text to it. So, if file1.txt has this text:
Hi! This is test from www.cpp-home.com!
Running the above code, will add “That’s new!” to it, so it will look this way:
Hi! This is test from www.cpp-home.com!That’s new!
If you want to set more than one open mode, just use the OR operator- |. This way:
ios::ate | ios::binary
I hope you now understand what open modes are!
Now, it’s time to show you something really useful! I bet you didn’t know that you could create a file stream handle, which you can use to read/write file, in the same time! Here is how it works:
fstream File("cpp-home.txt",ios::in | ios::out);
In fact, that is only the declaration. I will show you a code example, just several lines bellow. But I first want to mention some things you should know.
The code line above, creates a file stream handle, named “File”. As you know, this is an object from class fstream. When using fstream, you should specify ios::in and ios::out as open modes. This way, you can read from the file, and write in it, in the same time, without creating new file handles. Well, of course, you can only read or write. Then you should use either ios::in either ios::out, but if you are going to do it this way, why don’t you do it either with ifstream, either with ofstream?
Here is the code example:
#include

void main()
{
fstream File("test.txt",ios::in | ios::out);
File << "Hi!"; //put "Hi!" in the file
static char str[10]; //when using static, the array is automatically
//initialized, and very cell NULLed
File.seekg(ios::beg); //get back to the beginning of the file
//this function is explained a bit later
File >> str;
cout << str << endl;
File.close();
}

Okay, there are some new things here, so I will explain line by line:
fstream File("test.txt", ios::in | ios::out); - This line, creates an object from class fstream. At the time of execution, the program opens the file test.txt in read/write mode. This means, that you can read from the file, and put data into it, at the same time.
File << "Hi!"; - I beg you know what this is!
static char str[10]; - This makes a char array with 10 cells. I suppose static may be unfamiliar to you. If so- ignore it. It just initializes the array when at the time of creation.
File.seekg(ios::beg); - Okay, I want you to understand what this really do, so I will start with something a bit off-topic, but important.
Remember that? :
while(!OpenFile.eof())
{
OpenFile.get(ch);
cout << ch;
}

Did you ever wonder what really happens there? Yes or no, I will explain you. This is a while loop, that will loop until you reach the end of the file. But how do the loop know if the end of the file is reached? Well, when you read the file, there is something like an inside-pointer, that shows where you are up to, with the reading (and writing, too). It is like the cursor in Notepad. And every time you call OpenFile.get(ch) it returns the current character to the ch variable, and moves the inside-pointer one character after that, so that the next time this function is called, it will return the next character. And this repeats, until you reach the end of the file.
So, let’s get back to the code line. The function seekg() will put the inside-pointer to a specific place (specified by you). You can use:
ios::beg - to put it in the beginning of the file
ios::end - to put it at the end of the file
Or you can also set the number of characters to go back or after. For example, if you want to go 5 characters back, you should write:
File.seekg(-5);
If you want to go 40 character after, just write:
File.seekg(40);
I also have to mention, that the seekg() function is overloaded, and it can take two parameters, too. The other version is this one:
File.seekg(-5,ios::end);
In this example, you will be able to read the last 4 characters of the text, because:
1) You go to the end (ios::end)
2) You go 5 characters before the end (-5)
Why you will read 4 but not 5 characters? Well, just assume that one is lost, because the last thing in the file is not a character nor white space. It is just position.
You now may be wondering why did I use this function? Well, after I put “Hi!” in the file, the inside-pointer was set after it… at the end of the file. And as I want to read the file, I have nothing to read after the end, so I have to put the inside-pointer at the beginning. And that is exactly what this function does.
File >> str; - That’s new, too! Well, I believe this line reminds you of cin >> . I fact, it has much to do with it. This line reads one word from the file, and puts it into the specified array.
For example, if the file has this text:
Hi! Do you know me?
Using File >> str, will put just “Hi!” to the str array. You should have noticed, that it actually reads until it meets a white space.
And as what I put in the file was “Hi!” I don’t need to do a while loop, that takes more time to code. That’s why I used this way. By the way, in the while loop for reading, that I used so far, the program reads the file, char by char. But you can read it word by word, this way:

char str[30]; //the word can’t be more than 30 characters long
while(!OpenFile.eof())
{
OpenFile >> str;
cout << str;
}

You can also read it line by line, this way:

char line[100]; //a whole line will be stored here
while(!OpenFile.eof())
{
OpenFile.getline(line,100); //where 100 is the size of the array
cout << line << endl;
}

You now might be wondering which way to use? Well, I’d recommend you to use the line-by-line one, or the first that I mentioned- the one which reads char-by-char. The one that reads word-by-word is not good idea, because it won’t read the new line. So if you have new line in the file, it will not display it as a new line, but will append the text to the existing one. But using getline() or get() will show you the file, just as it is!
Now, I will show you how to check if the file opening was successful or not. In fact, there are few good ways to check for that, and I will mention them. Notice that where there is X, it can be either “o”, either “i” either nothing (it will then be fstream object).
Example 1: The most usual way

Xfstream File("cpp-home.txt");
if (!File)
{
cout << "Error opening the file! Aborting…\n";
exit(1);
}

Example 2: If the file is created, return an error
ofstream File("unexisting.txt", ios::nocreate);
if(!File)
{
cout << "Error opening the file! Aborting…\n";
exit(1);
}
Example 3: Using the fail() function
ofstream File("filer.txt", ios::nocreate);
if(File.fail())
{
cout << "Error opening the file! Aborting…\n";
exit(1);
}
The new in Example 3, is the fail() function. It returns a nonzero value if any I/O error (not end of file) has occurred.
I would also like to mention about something , that I find to be very useful! For example, if you have created a file stream, but you haven’t opened a file. This way:
ifstream File; //it could also be ofstream
This way, we have a handle, but we still have not opened the file. If you want to open it later, it can be done with the open() function, which I already covered in this tutorial. But if anywhere in your program, you need to know if currently there is an opened file, you can check it with the function is_open(). It retunrs 0 (false) if a file is not opened, and 1 (true) if there is an opened file. For example:
ofstream File1;
File1.open("file1.txt");
cout << File1.is_open() << endl;

The code above, will return 1, as we open a file (on line 2). But the code bellow will return 0, because we don’t open a file, but just create a file stream handle:
ofstream File1;
cout << File1.is_open() << endl;

Okay, enough on this topic.

Resetting a string

My prygram goes through a string to find names between '\'-characters
The problem is, parts of the name in sTemp remains if the new name is
shorter than the old name.

code
---------------------------------------------------
char sTemp[50];
char sText[] = "THELONGESTNAME\\samantha\\gregor\\spike\\..." ; // and
so on...

....
some code
....

int i=0;
while((sText[i] != '\\'))
{
sTemp[i] = sText[i];
i++;
}
printf("Name: %s\n",sNameBuff);
// Here i want to reset the string, totally empty it.
// this dosent do it.
sNameBuff == "";
// Start over again...
....


You don't show its definition or usage, but assuming
that 'sNameBuff' is a pointer to your string (or the
name of an array containing it), write:

*sNameBuff = 0;

or

sNameBuff[0] = 0;

There may indeed still exist characters in subsequent
memory locations, but because the first character
is now zero, subsequent characters are no longer part
of your string, it's "empty".



http://www.velocityreviews.com/forums/t317623-reset-a-string-empty-it-totally.html

Casting

Sunday, August 29, 2010

Why we have ++,-- operators

In those days compiler tech was old. There was 1 instruction - increment
So we have to link this ++ with increment...

But now a days optimizer finds itself and do the things accordingly.

Now a days these have got many problems, rather than solving it.

In cpp, people use pre increment rather than post-increment because of its copying data.

add = (++a) + (++a);
i = v[i++];

Using == operator in better way in cpp

In cpp, it is possible that instead of
i==5

we can do

i=5

So we assign i = 5 and if it is like
if(cond)
cond gets true.

So better is
5==i
beause == is symmetric.
If someone writes by mistake is
5=i
As we get error = 'can't assign value to literal'.

Thursday, August 12, 2010

Troubleshooting DNS servers

There may be broadly 2 problems we face when dealing with DNS server:
  • The DNS server is not responding to clients.
  • The DNS server does not resolve names correctly.
Dealing with them 1 by 1.

The DNS server is not responding to clients

Cause 1: Network failure

Solution: Check if the hardware is fully ok, i.e. adapters are properly plugged or not. Then check network connectivity by pinging other computers or routers (such as its default gateway) that are used and available on the same network as the affected DNS servers.


Cause2: Network is o.k. but non-responsive to client's query

Solution: If the DNS client can ping the DNS server, verify that the DNS server is started or not and is able to listen to client's request. Try using the nslookup command to test whether the server can respond to DNS clients. In ubuntu, if you can't run nslookup you need to install a package called dnsutils - which provide clients such as nslookup, host and other tools. The Berkeley Internet Name Domain (BIND) implements an Internet domain name server. his package delivers various client programs related to DNS that are derived from the BIND source tree. In windows use nslookup on command prompt.


Cause: The DNS server has been configured to limit service to a specific list of its configured IP addresses. The IP address originally used in testing its responsiveness is not included in this list.

Solution: If the server was previously configured to restrict the IP addresses for which it responds to queries, it is possible that the IP address being used by clients to contact it is not in the list of restricted IP addresses permitted to provide service to clients.

Try testing the server for a response again, but specify a different IP address known to be in the restricted interfaces list for the server. If the DNS server responds for that address, add the missing server IP address to the list.


Cause: The DNS server has been configured to disable the use of its automatically created default reverse lookup zones.

Solution: Verify that automatically created reverse lookup zones have been created for the server or that advanced configuration changes have not been previously made to the server.

By default, DNS servers automatically create the following three standard reverse lookup zones based on Request for Comments (RFC) recommendations:

These zones are created with common IP addresses covered by these zones that are not useful in a reverse lookup search (0.0.0.0, 127.0.0.1, and 255.255.255.255). By being authoritative for the zones corresponding to these addresses, the DNS service avoids unnecessary recursion to root servers in order to perform reverse lookups on these types of IP addresses.

It is possible, although unlikely, that these automatic zones are not created. This is because disabling the creation of these zones involves advanced manual configuration of the server registry by a user.


Cause: The DNS server is configured to use a non-default service port, such as in an advanced security or firewall configuration.

Solution: Verify that the DNS server is not using a non-standard configuration.

This is a rare but possible cause. By default, the nslookup command sends queries to targeted DNS servers using User Datagram Protocol (UDP) port 53. If the DNS server is located on another network only reachable through an intermediate host (such as a packet-filtering router or proxy server), the DNS server might use a non-standard port to listen for and receive client requests.

If this situation applies, determine whether any intermediate firewall or proxy server configuration is intentionally used to block traffic on well-known service ports used for DNS. If not, you might be able to add such a packet filter onto these configurations to permit traffic to standard DNS ports.

Also, check the DNS server event log to see if Event ID 414 or other critical service-related events have occurred which might indicate why the DNS server is not responding.


The DNS server does not resolve names correctly

Cause: The DNS server provides incorrect data for queries it successfully answers.

Solution: Determine the cause of the incorrect data for the DNS server.

Some of the most likely causes include the following:

  • Resource records (RRs) were not dynamically updated in a zone.
  • An error was made when manually adding or modifying static resource records in the zone.
  • Stale resource records in the DNS server database, left from cached lookups or zone records not updated with current information or removed when they are no longer needed.

To help prevent the most common types of problems, be sure to first review best practices for tips and suggestions on deploying and managing your DNS servers. Also, follow and use the checklists appropriate for installing and configuring DNS servers and clients based on your deployment needs.

If you are deploying DNS for Active Directory, note new directory integration features. These features can cause some differences for DNS server defaults when the DNS database is directory-integrated, that differ from those used with traditional file-based storage.

Many DNS server problems start with failed queries at a client, so it is often good to start there and troubleshoot the DNS client first.


Cause: The DNS server does not resolve names for computers or services outside of your immediate network, such as those located on external networks or the Internet.

Solution: The server has a problem based on its ability to correctly perform recursion. Recursion is used in most DNS configurations to resolve names that are not located within the configured DNS domain name used by the DNS servers and clients.

If a DNS server fails to resolve a name for which it is not authoritative, the cause is usually a failed recursive query. Recursive queries are used frequently by DNS servers to resolve remote names delegated to other DNS zones and servers.

For recursion to work successfully, all DNS servers used in the path of a recursive query must be able to respond to and forward correct data. If not, a recursive query can fail for any of the following reasons:
  • The recursive query times out before it can be completed.
  • A remote DNS server fails to respond.
  • A remote DNS server provides incorrect data.

If a server fails a recursive query for a remote name, review the following possible causes to troubleshoot the problem. If you do not understand recursion or the DNS query process, review conceptual topics in Help to better understand the issues involved.



Cause: The DNS server is not configured to use other DNS servers to assist it in resolving queries.

Solution: Check whether the DNS server can use both forwarders and recursion.

By default, all DNS servers are enabled to use recursion, although the option to disable its use is configurable using the DNS console to modify advanced server options. The other possibility where recursion might be disabled is if the server is configured to use forwarders and recursion has been specifically disabled for that configuration.


Cause: Current root hints for the DNS server are not valid.

Solution: Check whether server root hints are valid.

If configured and used correctly, root hints always should point to DNS servers authoritative for the zone containing the domain root and top-level domains.

By default, DNS servers are configured to use root hints appropriate to your deployment, based on the following available choices when using the DNS console to configure a server:

1. If the DNS server is installed as the first DNS server for your network, it is configured as a root server.

For this configuration, root hints are disabled at the server because the server is authoritative for the root zone.

2. If the installed server is an additional DNS server for your network, you can direct the Configure DNS Server Wizard to update its root hints from an existing DNS server on the network.

3. If you do not have other DNS servers on your network but still need to resolve Internet DNS names, you can use the default root hints file which includes a list of Internet root servers authoritative for the Internet DNS namespace.

Cause: The DNS server does not have network connectivity to the root servers.

Solution: Test for connectivity to the root servers.

If root hints appear to be configured correctly, verify that the DNS server used in a failed query can ping its root servers by IP address.

If a ping attempt to one root server fails, it might indicate that an IP address for that root server has changed. Reconfiguration of root servers, however, is uncommon.

A more likely cause is a full loss of network connectivity or in some cases, poor network performance on the intermediate network links between the DNS server and its configured root servers. Follow basic TCP/IP network troubleshooting steps to diagnose connections and determine whether this is the problem.

By default, the DNS service uses a recursive time-out of 15 seconds before failing a recursive query. Under normal network conditions, this time-out does not need to be changed. If performance warrants it, however, you can increase this value.

To review additional performance related information on DNS queries, you can enable and use the DNS server debug log file, Dns.log, which can provide extensive information about some types of service-related events.


Cause: Other problems exist with updating DNS server data, such as an issue related to zones or dynamic updates.

Solution: Determine whether the problem is related to zones. As needed, Troubleshoot any issues in this area, such as possible failure of zone transfer.