Common Memory/Pointer Related bug in C Programs
Last Updated :
01 Oct, 2018
Dereferencing an unknown memory location : C programmers mostly use scanf() function to take input, but sometimes a small mistake can bring a bug or even crash whole program.
The syntax for scanf() is
scanf("%d", &a);. It might be possible to miss a & and write
&a as a so now
scanf("%d", a); is dereferencing to an unknown location.
Now either the program may terminate with an exception or it may correspond to a valid location(not related to current program but to some other program) and may get overwritten which may cause unknown effect later.
C
// A C program to demonstrate that missing
// an & in scanf() may cause memory problems.
#include <stdio.h>
int main()
{
int a;
scanf("%d", a);
printf("%d", a);
return 0;
}
Reading an uninitialized Memory. In C, beginners generally use malloc() to provide run time memory but with malloc() the memory block do not get initialized and one may access .
C
// A C program to demonstrate that missing
// an & may cause memory problems.
#include <stdio.h>
int main()
{
int* p = (int*)malloc(sizeof(int) * 4);
int i;
// p[] contains some garbage value so
// below loop does not make any sense.
for (i = 0; i < 4; i++)
p[i] += 100;
}
A solution is to use calloc() instead which initialize block to 0.
Buffer overflow : This is a very common mistake that occur in C and this become even more common due to presence of a faulty function in C itself i.e. gets() function which is used to take string as input. It does not check the memory provided to store string in the program due to which if a user enter string of greater size then gets() with overwrite memory location after the string and cause overflow.
C
void read()
{
char str[20];
gets(str);
printf("%s", str);
return;
}
The code suffers from Buffer Overflow as gets() doesn't do any array bound testing. gets() keeps on reading until it sees a newline character. To avoid Buffer Overflow, fgets() should be used instead of gets() as fgets() makes sure that not more than MAX_LIMIT characters are read.
C
#define MAX_LIMIT 20
void read()
{
char str[MAX_LIMIT];
fgets(str, MAX_LIMIT, stdin);
printf("%s", str);
return;
}
Memory leaks This situation arises when the used heap memory is not de-allocated due to which the main memory get eventually filled up and free memory become less.
C
/* Function with memory leak */
#include <stdlib.h>
void f()
{
int* ptr = (int*)malloc(sizeof(int));
/* Do some work */
return; /* Return without freeing ptr*/
}
We should use free() after malloc() if memory is not used anymore.
C
/* Function without memory leak */
#include <stdlib.h>
void f()
{
int* ptr = (int*)malloc(sizeof(int));
/* Do some work */
free(ptr); // Deallocate memory
return;
}
Bug due to precedence Less understanding of operator and their precedence can produce a bug especially with pointers like
CPP
// C program to demonstrate bug introduced due
// to precedence.
#include <stdlib.h>
int demo()
{
int a = 10;
int* p = &a;
// intention was to increase the value of a
*p++;
}
Precedence of
* (dereference/indirection operator not multiplication) and postfix ++ are not same but prefix ++ and * has same, and hence, first the value of p will increase and will point to a bad memory area and then dereference and will overwrite that location or program may get terminated. Please see
Difference between ++*p, *p++ and *++p for details.
Sending address of non-existing variable Returning address of a local variable causes problems,
C
#include <stdlib.h>
int fun()
{
int x = 10;
return &x;
}
int main()
{
int* p = fun();
*p = 20;
}
When function fun() is called variable a is created but as soon function returns, it get destroyed. Since function is returned its address p will point to a memory area in stack area and if another function is called then a change by pointer
p may result in error.
Pointer arithmetic Pointer arithmetic can be confusing let's take an example suppose integer is of 4 Bytes.
CPP
int main()
{
int x[10] = { 0 }, i = 0, *p;
// p point to starting address of array x
p = &x[0];
while (i < 10) {
*p = 10;
// intention was to point to integer at x[1]
p = p + 4;
i++;
}
}
Although it seems correct as integer is of 4 byte and p is at starting location so adding 4 to it will cause p to point at next integer in array n but pointer arithmetic work according to size of its data type so adding 1 to a pointer of integer then sizeof(int) will get added to it same applies for pointer to any other data type.
CPP
int main()
{
int x[10] = { 0 }, i = 0, *p;
p = &x[0]; // p point to starting address of array x
while (i < 10) {
*p = 10;
p++; // means p = p + sizeof(int)
i++;
}
}
Passing array as parameter When we pass an array to a function, it is always treated as a pointer in the function. That's why we should never use sizeof on array parameter. We should rather always pass size as a second parameter.
C
#include <stdio.h>
// arr is a pointer even if we have
// use square brackets.
void printArray(int arr[])
{
int i;
/* sizeof should not be used here to get number
of elements in array*/
int arr_size = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < arr_size; i++) {
printf("%d ", arr[i]);
}
}
int main()
{
int arr[4] = { 1, 2, 3, 4 };
printArray(arr);
return 0;
}
Below is the corrected code
C
#include <stdio.h>
// arr is a pointer even if we have
// use square brackets.
void printArray(int arr[], int arr_size)
{
int i;
for (i = 0; i < arr_size; i++) {
printf("%d ", arr[i]);
}
}
int main()
{
int arr[] = { 1, 2, 3, 4 };
int arr_size = sizeof(arr) / sizeof(arr[0]);
printArray(arr, arr_size);
return 0;
}
Reference :
Computer Systems :A programmer's Perspective
Similar Reads
Output of C programs | Set 64 (Pointers)
Prerequisite : Pointers in C Question 1 : What will be the output of following program? C #include "stdio.h" int main() { char a[] = { 'A', 'B', 'C', 'D' }; char* ppp = &a[0]; *ppp++; // Line 1 printf("%c %c ", *++ppp, --*ppp); // Line 2 } OPTIONS: a)C B b)B A c)B C d)C AOUTPUT: (d) C AExplanati
3 min read
Output of C++ programs | Set 38 (Pointers)
Prerequisite : Pointers in C/ C++ QUE.1 What would be printed from the following C++ program? C++ #include <iostream> using namespace std; int main() { int x[5] = { 1, 2, 3, 4, 5 }; // p points to array x int* p = x; int i; // exchange values using pointer for (i = 0; i < 2; i++) { int temp
4 min read
Output of C++ programs | Set 47 (Pointers)
Prerequisite : Pointers in C/C++ 1. What will be the output of the following program? CPP #include <iostream> using namespace std; int main() { int a = 32, *ptr = &a; char ch = 'A', &cho = ch; cho += a; *ptr += ch; cout << a << ", " << ch << endl; retu
4 min read
Output of C++ programs | Set 39 (Pointers)
Prerequisite: Pointers in C/C++ QUE.1 What would be printed from the following C++ program? CPP #include <iostream> #include <stdlib.h> using namespace std; int main() { float x = 5.999; float* y, *z; y = &x; z = y; cout << x << ", " << *(&x) <<
4 min read
Memory Layout of C Programs
The memory layout of a program refers to how the programâs data is stored in the computer memory during its execution. Understanding this layout helps developers manage memory more efficiently and avoid issues such as segmentation faults and memory leaks.A C program's memory is organized into specif
5 min read
Output of C programs | Set 60 (Constants)
Prerequisite: C Constants and StringsQ.1 What is the output of this program? C#include <stdio.h> int main() { const char *s = ""; char str[] = "Hello"; s = str; while(*s) printf("%c", *s++); return 0; } Options a) Error b) H c) Hello d) Hel ans:- c Explanation const char *s = "";The constant v
3 min read
Output of C Programs | Set 3
Predict the output of the below program. Question 1 c #include <stdio.h> int main() { printf("%p", main); getchar(); return 0; } Output: Address of function main. Explanation: Name of the function is actually a pointer variable to the function and prints the address of the function.
3 min read
Commonly Asked C Programming Interview Questions | Set 1
What is the difference between declaration and definition of a variable/functionAns: Declaration of a variable/function simply declares that the variable/function exists somewhere in the program but the memory is not allocated for them. But the declaration of a variable/function serves an important
5 min read
Output of C Programs | Set 2
Predict the output of below programs. Question 1 c #include<stdio.h> char *getString() { char str[] = "Will I be printed?"; return str; } int main() { printf("%s", getString()); getchar(); } Output: Some garbage value The above program doesn't work because array variables a
2 min read
Output of C Programs | Set 7
Predict the output of below programsQuestion 1 c int main() { int i = 0; while (i <= 4) { printf("%d", i); if (i > 3) goto inside_foo; i++; } getchar(); return 0; } void foo() { inside_foo: printf("PP"); } Output: Compiler error: Label "inside_foo" used but not defined.Expl
2 min read