Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
195 views

Common Memory - Pointer Related Bug in C Programs - GeeksforGeeks PDF

This document discusses several common memory and pointer-related bugs in C programs: 1. Dereferencing an unknown memory location, such as missing the "&" with scanf(), can cause a program to crash or overwrite unrelated memory. 2. Reading uninitialized memory, like accessing values in memory allocated with malloc() without initializing, can cause unpredictable behavior. 3. Buffer overflows occur when functions like gets() read more input than the buffer can hold, overwriting other memory. 4. Memory leaks happen when dynamically allocated memory is no lost freed, filling available memory. It also discusses issues with operator precedence, returning addresses of local variables, pointer arithmetic, passing arrays to functions

Uploaded by

Krishanu Modak
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
195 views

Common Memory - Pointer Related Bug in C Programs - GeeksforGeeks PDF

This document discusses several common memory and pointer-related bugs in C programs: 1. Dereferencing an unknown memory location, such as missing the "&" with scanf(), can cause a program to crash or overwrite unrelated memory. 2. Reading uninitialized memory, like accessing values in memory allocated with malloc() without initializing, can cause unpredictable behavior. 3. Buffer overflows occur when functions like gets() read more input than the buffer can hold, overwriting other memory. 4. Memory leaks happen when dynamically allocated memory is no lost freed, filling available memory. It also discusses issues with operator precedence, returning addresses of local variables, pointer arithmetic, passing arrays to functions

Uploaded by

Krishanu Modak
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 3

Common Memory/Pointer Related bug in C Programs


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.

// 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 .

// 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 over ow : 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 over ow.

void read()
{
    char str[20];
    gets(str);
    printf("%s", str);
    return;
}

The code suffers from Buffer Over ow as gets() doesn’t do any array bound testing. gets() keeps on reading until it sees a newline character. To
avoid Buffer Over ow, fgets() should be used instead of gets() as fgets() makes sure that not more than MAX_LIMIT characters are read.

#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 lled up and
free memory become less.
/* 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.

/* 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

// 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 post x ++ are not same but pre x ++ and * has same, and hence,
rst 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,

#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.

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.

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.

#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

#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

You might also like