Although pointers are very useful in c they are not free from limitations. If used incorrectly, pointers can lead to bugs that are difficult to unearth.
DRAWBACKS
OF POINTERS
Although
pointers are very useful in c they are not free from limitations. If used
incorrectly, pointers can lead to bugs that are difficult to unearth. For
example, if you use a pointer to read a memory location but that pointer is
pointing to an incorrect location then you may end up reading a wrong value. An
erroneous input always leads to an erroneous output, therefore however efficient
your program code may be, the output will always be disastrous. Same is the
case when writing a value to a particular memory location.
Consider
a scenario in which the program code is supposed to read the account balance of
a customer, add new amount to it, and then re-write the modified value to that
location. If the pointer is pointing to the account balance of some other
customer then the account balance of the wrong customer will be updated.
Let
us try to find some common errors encountered when using pointers.
int x, *px;
x = 10;
*px = 20;
Error un-initialized
pointer. px is pointing to an unknown memory location. Hence it will overwrite
that location's contents and store 20 in it. Such pointer is called a wild
pointer. A pointer which is not initialized with any address is called a wild
pointer. It may contain any garbage address and thus dereferencing a wild
pointer can be dangerous.
int x, *px;
x = 10;
px = x;
ERROR: it should be px = &x;
int x = 10, y = 20, *px, *py;
px = &x, py = &py ;
if (px < py) // it should be *px
and *py
printf("\n px is less than
py");
else
printf("\n py is less than
px");
Look
at another code given below.
#include <stdio.h>
main()
{
char *strl, *str2;
printf("\n Enter the string:
");
gets (str1);
while (*str1!= '\0')
{
*str2 = *str1;
str2++, str1++;
}
*str2='\0';
printf("\n String is: ");
while (*str2 != '\0')
{
printf("%c", *str2);
str2++;
}
}
Error str2
will not be printed because str2 has moved ahead of its starting location and
before displaying the string, it has not been initialized with its starting
address.
Memory leak
Memory leakage occurs when memory is allocated but not released when it is no
longer required. This causes an application to unnecessarily consume memory
thereby reducing the memory available for other applications. Although in small
programs it is not a big concern but when dealing with large projects, memory
leakage may result in slowing down the application or crashing the application
when the computer memory resource limits are reached.
For
example, if a function dynamically allocates memory for 100 double values and
forgets to free the memory and in worst case if that function is called several
times within the code then ultimately the system may crash.
Dangling pointer
Dangling pointers arise when an object is deleted or de-allocated, without
modifying the value of the pointer. As a result, the pointer still points to
the memory location of the de-allocated memory.
Once
the memory is de-allocated, the system may reallocate that block of freed memory
to another process. In case the program then dereferences the (now) dangling pointer,
unpredictable behaviour may result, as the memory may now contain completely
different data.
This
problem can become worse when the program writes data to memory pointed by a
dangling pointer causing a silent corruption of unrelated data, leading to
subtle bugs that can be extremely difficult to find. Moreover, if the
overwritten data is bookkeeping data used by the system's memory allocator, the
corruption can even cause system instabilities.
Hence,
dangling pointer problem occurs when the pointer still points to the same
location in memory even though the reference has been deleted and may now be
used for other purposes.
A
common mistake that we often do in C program is to return address of a
stack-allocated local variable. We know that once a called function returns,
the space for these variables gets de-allocated and technically they have
garbage values. Look at the code below which illustrates how we get a dangling
pointer when a called function returns.
char *func (void)
{
Char ch='A';
/* ... */
return & ch;
}
The
above program returns the address of ch. So the calling function may access its
value. Any functions called thereafter will overwrite the stack storage
allocated for ch with other values and the pointer would no longer work
correctly. Therefore, if a pointer to ch must be returned it must be declared
as static.
Consider
the code below which illustrates another dangling pointer problem.
char *ptr1;
char *ptr2 = (char
*)malloc(sizeof(char));
ptr1 = ptr2;
free (ptr2);
Now
ptr1 becomes a dangling pointer. A solution to the above is to assign 0 (null)
to ptr1 immediately before exiting the block in which it is declared. An
alternative solution would be to somehow guarantee that ptr1 will not be used
again without further initialization.
Memory corruption
Memory corruption often occurs when due to programming errors, the contents of
a memory location gets modified unintentionally. When the program uses the contents
of the corrupted memory, it either results in program crash or in strange and
bizarre behaviour.
Memory
corruption is one of the most difficult pro- gramming errors to trace mainly
because of two reasons:
•
The source of the memory corruption and its manifestation may be far apart.
Therefore, it may become hard to correlate the cause and the effect of the
problem.
•
Symptoms of memory corruption problem may appear under unusual conditions
thereby making it even harder to consistently reproduce the error.
Memory
corruption errors can be broadly classified into following categories:
1.
Using
un-initialized memory: An un-initialized ai m memory contains garbage
value. Hence, using the contents of an un-initialized memory can lead to
unpredictable program behaviour.
2.
Using
un-owned memory: A common programming mistake is to use pointers for
accessing and modifying memory that is not owned by the program. This situation
may arise when the pointer happens to be a null pointer or a dangling pointer.
Using such a pointer to write to a memory location is a serious programming
flaw as it may lead to crash another program or even the operating system.
3.
Using
beyond allocated memory (buffer overflow): If the elements of the array
are accessed in a loop, with incorrect terminating condition, memory beyond the
array bounds may be manipulated. Buffer overflow is a common programming flaw
exploited by computer viruses causing serious threat to computer security.
4.
Faulty
de-allocation of memory: Memory leaks and freeing un-allocated memory
can also result in memory corruption.
These
days, memory debuggers like Purify,
Valgrind, Insure++ are widely used for detecting memory corruption errors.
Programming in C: Unit III (b): Pointers : Tag: : Programming in C - Drawbacks of Pointers
Programming in C
CS3251 2nd Semester CSE Dept 2021 | Regulation | 2nd Semester CSE Dept 2021 Regulation