White Box Testing
Test your code
   Home      MemoryCorruption
 

Memory Corruption (Memory Access Errors)

Memory Corruption happens when content of a memory location are unintentionally modified due to programming errors. When the corrupted memory contents are used later in the computer program, it leads either to program crash or to strange and bizarre program behavior. Memory corruption errors can be broadly classified into four categories:
 
  1. Invalid Array Indexing or Buffer overflow
  1. Uninitialized memory uses or Wild pointers
  1. Unowned memory uses or Dangling pointer
  1. Faulty heap memory management.
  1. Incorrect function argument.
  1. Invalid system operations.

 

Memory corruption in C,C++:
1) Invalid Array Indexing (Buffer overflow): C,C++ do not support array bound checking.Invalid array indexing or buffer overlap is one of the biggest source of crashes in C and C++ programs. Out of bound array indexing will corrupt data structures that allocated memory after the array.Common scenario occurs in case of  Out of bound array indexing or buffer overflow
   
    If the whole part X of the memory belongs to the running program, then:
a) IfX does not contain any data important for the rest of the execution of the program or  contain important data that are overridden tail of the binary code but by chance this does not change  anything then the program runs fine and there is no problem.
b) If X does contain important data that are overridden and thus changed, then
  • incorrect results may be produced or
  • the program may crash with all kinds of possible error messages.
 
If all or part of X belongs to some other process, then the program is terminated by the operating system with memory access violation (segmentation fault error).
 
a) Out of bound array indexing:
      {
  int a[5];
  . . .
  . . .
  for ( i = 0; i <=5; i++)
        a[i] =  i;
                  }
 
b) Buffer Overflow
Char *buffer = malloc(strlen(buffer2)); 
      strcpy(buffer, buffer2)
      buffer size is 1 byte less than buffer 2. Thus causes buffer overflow
 
2) Uninitialized memory uses(Wild pointers): Created by omitting  initialization prior to first use. Generally global and static variable initialized by compiler if we have not explicitly. While local variables contains garbage values if we have not initialized them.using such uninitialized variables causes bizarre program behavior
Class ABC
{
    String name;
    
 
}
ABC  *p;
Char *p  =  p -> name; //used without initializing p
 
3) Unowned memory uses (Dangling pointer): A dangling pointer is a pointer to storage that is no longer allocated, that do not point to a valid object of the appropriate type. If a pointer is pointed to an object that is later deallocated, the pointer is left dangling. There are two ways for dangling to happen, explicit and implicit. In the explicit way, the pointer is first pointed to a dynamically allocated memory that is later explicitly deallocated without resetting the pointer to NULL. In implicit way, the pointer is pointed to a local object that is then later deallocated.
            Explicit dangling references
             {
char *p = malloc(sizeof(char));
          ..
          free(p);
          cout << p << endl;  // This will probably work but dangerous.
    }     
 
            Implicit dangling references
             {
                    int  *p = NULL ;
          {
                     int c;
           p = &c;
                    }
                  // here p is now dangling pointer    
             }   
A popular technique to avoid dangling pointers is to use smart pointers. A smart pointer typically uses reference counting to reclaim objects

4)  Faulty heap memory management :
a) Freeing/deleting memory which has already been freed.
                char *p = malloc(sizeof(char));
                . . .
                free(p);
                . . .
                . . .
                free(p);
 
            b) Freeing/deleting memory which has not been dynamically allocated.
            {
                  int  *p =  NULL ;
                  int c;
                  p  = &c;
                  free(p);   
            }   
            c) Incorrect use of delete
            {
                 string *p =  new string(“hello” );
                 . . .
                 . . .
                delete [] p;
             }
 
5)  Incorrect function argument: Occurs in case of when a program passes a pointer of the wrong type to a function.
 void func1( long *p)
{
  . . .
  . . .
}
 
int main( )
           {
    string *p ;
    . . .
    func1( p );
    . . .
    return 0;
}
 
6)  Invalid system operations:
1)     Try to access invalid memory used by operating system.
2)     Accessing to misaligned memory.
3)     User mode processes try to execute process restricted only to kernel mode.
 
 
 
Memory corruption in Java
 
The single biggest difference between Java and C/C++ is that Java has a pointer model that eliminates the possibility of overwriting memory and corrupting data. Instead of pointer arithmetic, Java has true arrays. This allows subscript checking to be performed. In addition, it is not possible to turn an arbitrary integer into a pointer by casting. Java is robust and secure: you don't have to worry about freeing or corrupting memory. Java programmers can be relatively fearless about dealing with memory because they don't have to worry about it getting corrupted. Because there are no pointers in Java, programs can't accidentally overwrite the end of a memory buffer. Java programs also cannot gain unauthorized access to memory, which could happen in C or C++.
 
 
 

External References