The
segmentation fault is the most frequently occurred runtime error in
the C/C++ program compiled using gcc/g++. I have seen that students
use TurboC++ compiler because it doesn't show the error like
“segmentation fault”. Today's engineering students does not take
any efforts to analyze why such kinds of problems occurs?
A
program use memory space allocated to it which uses the stack and
heap area. The memory is allocated here using runtime. For this we
use the malloc function or new operator. Now, when the following
situations occur, the program will show the “segmentation fault”.
-
Memory is not released using delete/free.
-
Using the array index which is not in the specified range.
-
The uninitialized pointer is referenced in the program.
-
Read only memory is attempted to be used for writing.
-
Already freed pointer is dereferenced.
In
order to find the reason of such different kinds of memory problem,
we may use the valgrind which is a memory checker utility provided by
the Linux system. It is used along with GDB. It is not possible for
GDB to find the memory errors in one stroke, so valgrind can be used. It
is useful in many scenarios of C/C++ programming. Few of these are
discussed in this blog post. Valgrind is used to notify the user with
all the errors as given above. Generally, memory leakage problems can
be easily detected by the valgrind. As the gcc is very robust
compiler, the system tool is very much useful in the programming.
In
order to download the valgrind latest version, use the following
command on debian based Linux systems such as Ubuntu/Mint.
sudo
apt-get install valgrind
or
use following to install it on Redhat based Linux.
sudo
yum install valgrind
As
C/C++ don't have any automatic garbage collector, valgrind can be
used to identify the garbages in the program. Lets write a simple
program in C++.
#include<iostream>
using
namespace std;
int
main()
{
int
*x;
x
= new int(10);
return
0;
}
This
program is creating an array of 10 numbers using pointers. So, the
memory of 10 locations is allocated to variable x using new operator.
Now, compile the program by enabling the debugger to it using
following command.
g++
-g prog.cpp -o prog
It
will create the executable file named prog. Now use valgrind
to check for the memory problems.
valgrind
--tool=memcheck --leak-check=yes ./prog
This
uses the tool “memcheck” by enabling the checking of the memory
leakage ability.
==3550==
Memcheck, a memory error detector
==3550==
Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==3550==
Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==3550==
Command: ./prog
==3550==
==3550==
==3550==
HEAP SUMMARY:
==3550==
in use at exit: 4 bytes in 1 blocks
==3550==
total heap usage: 1 allocs, 0 frees, 4 bytes allocated
==3550==
==3550==
4 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3550==
at 0x402B733: operator new(unsigned int) (in
/usr/lib/valgrind/vgpreload _memcheck -x86-linux.so)
==3550==
by 0x80485B0: main (prog.cpp:6)
==3550==
==3550==
LEAK SUMMARY:
==3550==
definitely lost: 4 bytes in 1 blocks
==3550==
indirectly lost: 0 bytes in 0 blocks
==3550==
possibly lost: 0 bytes in 0 blocks
==3550==
still reachable: 0 bytes in 0 blocks
==3550==
suppressed: 0 bytes in 0 blocks
==3550==
==3550==
For counts of detected and suppressed errors, rerun with: -v
==3550==
ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Here,
3550 is the process ID of your program. It has shown that the program
has definitely lost 4 bytes in 1 block. This is shown because that
the memory allocated is not freed. After adding 'delete x' statement
at the end of the program, we will get this message using valgrind.
All
heap blocks were freed -- no leaks are possible
Lets
use the variable x[15] from the given array. It is not possible to
use this variable from the array! I will write the following
statement in the program.
x[15]
= 34;
Now,
valgrind shows the following statements:
==3608==
Invalid write of size 4
==3608==
at 0x80485C2: main (prog.cpp:7)
==3608==
Address 0x4330064 is not stack'd, malloc'd or (recently) free'd
It
means the line number 7 of prog.cpp has “invalid write of size 4
bytes”! We will easily identify that the memory is used in some
wrong way in the program. Remember it is not a syntactical mistake!
Now
when we use the uninitialized data in the program such as,
if
(x[1]==1)
x[1]
= 0;
As
the array is not initialized, the x[1] won't contain any value in it.
When you compile the program and analyze it by valgrind, you will get
the following output.
==3661==
Invalid read of size 4
==3661==
at 0x80485C2: main (prog.cpp:7)
==3661==
Address 0x433002c is 0 bytes after a block of size 4 alloc'd
==3661==
at 0x402B733: operator new(unsigned int) (in
/usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==3661==
by 0x80485B0: main (prog.cpp:6)
This
is the error for uninitialized data in the program. You will identify
that the statement on line number 6 has some uninitialized data
variable in it.
I
think using valgrind improves the quality of software development. A
software developer must use it in order to solve the memory leakage
problems. It has many features, you may use 'man valgrind' to see all
these features of it.
Enjoy
good programming!