C++ A step towards streaming input from fixed array.

Objectives :

The input and output operations from keyboard in C++ language have significantly enhanced over it's ancestors. In this example we intend present a risk of using an array of predefined size with cin object of iostream, and compared with get(...) function.

  • File Name : gets_unsafe1.cpp
  • gets () function of "stdio.h" : It reads  bytes of string from keyboard. The iostream header file still support this function.
    • Prototype:  char * gets ( char * ch1); // uses pointer
      This function gets everything you type, stores as a c-string, and it does not set a limit on the size and type of data. Therefore, it ignores  the size of an array.
      • Syntax  : In the following construct, with get() function you can receive characters more than the specified length.
        char cstr1[12]; 
        gets(cstr1); //reads and stores input into an array
        char * p1= new char[strlen(cstr1)+1];
        strncpy(p1, cstr1,strlen(cstr1)+1);
  • Buffer-overflow : In the following syntax, if user feeds a string which is more than the defined size, such action results into a condition which is known as buffer-overflow. The results of a buffer-overflow will be unpredictable.
    • Syntax :
      cin.getline(cstr1, 12);//extracts characters into C-string
      cout<<"\n String cstr1 : "<<cstr1<<"\n\t is now "<<strlen(cstr1);
      char * p1= new char[strlen(cstr1)+1];

  • Why to use new operator in C++?
    • Without new, all the local objects are allocated on the stack (where all local variables will go). In general there is less memory available for the stack; if you allocate too many objects on the stack, you end up with a stack overflow.
  • Code: gets_unsafe1.txt

Step: 1 Create a source file.

Step: 2 Edit and save Source file

Step: 3 Runtime Views:

a) Ignoring array size: Note in this case, the function, gets( array or pointer ), gets everything you feed. This function reads the input and stores into an array. You can pump any data using gets function overriding the size constraints of the parameter-variable. 

The oversized string was accepted and now pointer with new[] operators, allocated this array at an address on the heap, and  returned a pointer to the beginning of the new block of memory allocated.

Note the new operator sets  a non-null pointer to the first byte of the newly allocated string.

b) iostream fail state  with cin.getline(ch1, 15): Note that oversized data, ignored rest of the code. With an error in the stream, due to incorrect orders of data or data type mismatch, cin object enters a fail-state and all the subsequent stream operations are ignored.

Step: Brief Discussion:  This example shows the risks involved in using "gets(parameter)" function, and these risks can be eliminated with dynamic streaming with iostream. The iostream schemes are empowered with cin and cout objects, and an efficient error handling routines. The cin object suspends input-streaming in case of any error, thereby preventing an application from crashing (Please refer cin_stream1.htm).

As C++ introduced streaming in real sense and terms ( iostream_cin_cout1.htm ), the function "gets(string)", is a step back towards the C-string concepts. Please review this example, where I used a string object to get user's input from key board, and then initialized a character array. char_new_delete1.htm.

Unsafe gets(array): The function, get() of , is not safe and can misbehave.

An application may crash with gets(array) function: Since gets function does not define size limit and does not have error handling supports; the users can enter a very long string and that may crash the application, as shown in the illustration below.

gets(...) function can misbehave: In some IDE, like Eclipse CDT, gets() function did not blend along with  objects from iostream. In the following example, compiler did not process it's (gets() function) instructions. ( You need to tune up your Eclipse software to support C99  I found a nice hands on article http://bitvector.net/?p=75) . I tested in windows 32 and 64 bit OS, most of the old C codes worked, but strolled with gets(..) function).

cin object and buffer-overflow :

In this example, the function "cin.getline(cstr1, 12)", contains an array with predefined storage size. An array stores homogenous data, and the size of the array must be declared before using. The reference of fixed size arrays are stored in an area known as "stack".

The stack is a storage area, and is used to store data declared implicitly (pre-defined). The data is stored in stack using the Last In First Out (LIFO) method. The array elements are stored in the stack and the compiler will verify the size allocated for this array. When  you feed a string which exceeds the allocated size, compiler will fail to process the oversized-string, and cause buffer-overflow.

A buffer overflow, as we see in one of the illustrations, is an anomaly where the input streams overruns the  allocated space. This may cause many unexpected results, erratic application behavior, unexpected output, violate security rules or a crash. The error handling schemes of isostream, recognizes  such errors, enters the a fail-state, and ignores all references to input-stream operations. C language does not provide such operations.

Special Notes:

The stack is a place in the computer memory, where all the predefined variables are stored and initiated, before runtime. The heap is also a storage area in the computer memory, and is used for dynamic memory allocation. The stack is smaller, but faster than heap.