100% found this document useful (2 votes)
179 views

Dangling Pointers and Garbage Memory

Three common problems involving pointers are: 1) Dangling pointers, which occur when a pointer is dereferenced after the memory it points to has been freed or reallocated. 2) Garbage memory, which occurs when a pointer is reassigned so that the memory it originally pointed to can no longer be accessed, resulting in memory waste. 3) Array index violations, which occur when an array is accessed using an index that is less than 0 or greater than or equal to the array size. Dereferencing dangling pointers or violating array indices typically results in a segmentation fault.

Uploaded by

Sandy
Copyright
© © All Rights Reserved
Available Formats
Download as ODP, PDF, TXT or read online on Scribd
100% found this document useful (2 votes)
179 views

Dangling Pointers and Garbage Memory

Three common problems involving pointers are: 1) Dangling pointers, which occur when a pointer is dereferenced after the memory it points to has been freed or reallocated. 2) Garbage memory, which occurs when a pointer is reassigned so that the memory it originally pointed to can no longer be accessed, resulting in memory waste. 3) Array index violations, which occur when an array is accessed using an index that is less than 0 or greater than or equal to the array size. Dereferencing dangling pointers or violating array indices typically results in a segmentation fault.

Uploaded by

Sandy
Copyright
© © All Rights Reserved
Available Formats
Download as ODP, PDF, TXT or read online on Scribd
You are on page 1/ 29

2 Common Problems involving Pointers:

(Dereferencing) Dangling Pointers


And
Garbage Memory
Dangling Pointers
A pointer is dangling when declared & not initialized


A pointer becomes non dangling, when assigned to a
“good” memory location like local variables, global
variables, malloc-ed memory

A pointer can become dangling again due to mistakes in
pointer arithmetic
Mistakes in manipulation of dynamically allocated

memory, e.g. Linked list pointers


On deallocation of malloced memory using free()

etc
Dangling Pointers
Ø
Total 3 Possibilities for a pointer value
Ø
Points to memory owned by program
Local variables, Global Variables, Malloced Memory
Ø
= NULL
Ø
Dangling
Ø Some texts differentiate between ‘wild’ (uninitialized) and ‘dangling’
pointers
Ø
Dereferencing (that is * ) a dangling (or NULL) pointer is NOT to be done
Ø
Even if you find that dereferencing a dangling pointer “does not create
problem” in your code, it is still not to be done!
Ø
Result: The OS terminates the code giving
“Segmentation Fault”
int main() {
int *p, i, j, *q;// p,q are dangling
}

p i q j

Dangling Pointers Example: 1


int main() {
int *p, i, j, *q;// p,q are dangling
p = &i; // p not dangling
}

p i q j

Dangling Pointers Example: 1


int main() {
int *p, i, j, *q;// p,q are dangling
p = &i; // p not dangling
i = 10; // *p = 10
}

p I = 10 q j

Dangling Pointers Example: 1


int main() {
int *p, i, j, *q;// p,q are dangling
p = &i; // p not dangling
i = 10; // *p = 10
q = &j; // q not dangling
}

p I = 10 q j

Dangling Pointers Example: 1


int main() {
int *p, i, j, *q;// p,q are dangling
p = &i; // p not dangling
i = 10; // *p = 10
q = &j; // q not dangling
q = (int *)malloc(sizeof(int) * 4);
// q not dangling
}

p I = 10 q j

Dangling Pointers Example: 1


int main() {
int *p, i, j, *q;// p,q are dangling
p = &i; // p not dangling
i = 10; // *p = 10
q = &j; // q not dangling
q = (int *)malloc(sizeof(int) * 4);
// q not dangling
q = q + 3; // q not dangling
}

p I = 10 q j

Dangling Pointers Example: 1


int main() {
int *p, i, j, *q;// p,q are dangling
p = &i; // p not dangling
i = 10; // *p = 10
q = &j; // q not dangling
q = (int *)malloc(sizeof(int) * 4);
// q not dangling
q = q + 3; // q not dangling
q = q + 1; // q IS dangling now
}

p I = 10 q j

Dangling Pointers Example: 1


int main() {
int *p, i, j, *q;// p,q are dangling
p = &i; // p not dangling
i = 10; // *p = 10
q = &j; // q not dangling
q = (int *)malloc(sizeof(int) * 4);
// q not dangling
q = q + 3; // q not dangling
q = q + 1; // q IS dangling now
p = q - 6; // p IS also dangling
}

p I = 10 q j

Dangling Pointers Example: 1


typedef struct node { p q
int val;
struct node *next;
}node;
int main() { a
node *p, *q; Val
node a;
} next

Dangling Pointers Example: 2


typedef struct node { p q
int val;
struct node *next;
}node;
int main() { a
node *p, *q; Val =20
node a;
a.val = 20; next
}

Dangling Pointers Example: 2


typedef struct node { p q
int val;
struct node *next;
}node;
int main() { a
node *p, *q; Val =20
node a;
a.val = 20; next
p = &a;

Dangling Pointers Example: 2


typedef struct node { p q
int val;
struct node *next;
}node;
int main() { a
node *p, *q; Val =20
node a;
a.val = 20; next
p = &a;
a.next = (node *)malloc(sizeof(node));
Val
}

next

Dangling Pointers Example: 2


typedef struct node { p q
int val;
struct node *next;
}node;
int main() { a
node *p, *q; Val =20
node a;
a.val = 20; next
p = &a;
a.next = (node *)malloc(sizeof(node));
a.next->val = 50;
Val=50

}
next

Dangling Pointers Example: 2


typedef struct node { p q
int val;
struct node *next;
}node;
int main() { a
node *p, *q; Val =20
node a;
a.val = 20; next
p = &a;
a.next = (node *)malloc(sizeof(node));
a.next->val = 50;
Val=50
q = a.next;

} next

Dangling Pointers Example: 2


typedef struct node { p q
int val;
struct node *next;
}node;
int main() { a
node *p, *q; Val =20
node a;
a.val = 20; next
p = &a;
a.next = (node *)malloc(sizeof(node));
a.next->val = 50;
q = a.next;
free(a.next);

Dangling Pointers Example: 2


typedef struct node { p q
int val;
struct node *next;
}node;
int main() { a
node *p, *q; Val =20
node a;
a.val = 20; next
p = &a;
a.next = (node *)malloc(sizeof(node));
a.next->val = 50;
q = a.next;
free(a.next);
q->val = 100; // segfault

Dangling Pointers Example: 2


Remember

Dereferencing a dangling pointer is a cause of
segmentation fault
Dereferencing can occur using * or [ ]


Having a dangling pointer does not cause
segmentation fault
Dereferencing it causes


Having dangling pointers is not wrong, but why
have them?
Garbage ●
p was pointing to malloced memory

In the end p points to i
Memory ●
How to access the malloced memory now?

No way! It's Lost!
int *p, i; ●
It became “garbage memory”

p = malloc ●
Problems like this result in memory waste

Also called as Memory leak
(sizeof(int) * 4); ●
Solution
p = &i; Keep another point pointing to malloced

memory
i ●
p = malloc(sizeof(int) * 4);

q = p;

p = &i;
p ●
Malloced memory is available through
0 1 2 3 pointer q
Segmentation Fault
What is segmentation fault?
A program accessing an “illegal” memory location

Is punished by the operating system for doing so


The program gets “terminated” (killed)



“segmentation” comes from “memory management” concepts in
operating systems
It is ALWAYS a fault of the programmer!

Beware


Bad compilers may generate machine code which hide some memory
violations

If a programmer does illegal memory access, segmentation fault may not
occur sometimes!
–OS may “forgive” your program :-;
Some Typical Reasons for Seg-fault
Deferencing Dangling Pointers

Array Index Violation

Incorrect Function Arguments


Dangling Pointer Dereference: Some
examples int *f(int *p) {
int *p, i;
int x = *p + 2;
*p = 20;
return &x;
int *p, i;
}
p = malloc( sizeof(int)*2);
int main() {
free(p);
int i, *q;
p[2] = 20;
scanf(“%d”, &i);

int *p, i; q = f(&i);


p = &i; *q = 20;
p[1] = 20; }
Don't return address of a local variable! The variable
disappears after function call, and the returned address
is a dangling pointer.
Array Index Violation
Valid indices for an array of size n: 0 .. n-1
Accessing any index <= -1 or >= n may result in seg-fault
(it may not result in some cases, but it is STILL WRONG to do it!)
#include <stdio.h>
Try this code: int main() {
At what value int a[16], i = 0;
of i does the while(1) {
a[i] = i;
code seg-fault? printf("%d\n", a[i]);
Try 2-3 times. i++;
}
}

Reason: OS may allocate more than 16-integer size


memory for the program. So the seg fault may not occur
at index 16 or slightely higher indices also. Rule: wrong to
access index >=n
Functions: Pointer Arguments

Rule: When you want a function to change ACTUAL arguments

Function takes pointer arguments

Call passes address of “actual argument”

Example: Swap function (correct code)
void swap(int *a, int *b ) {

int temp;
temp = *a;
*a = * b;
*b = temp;
}
int main() {
int m = 20, n = 30;
swap(&m, &n);
}
Incorrect Pointer Aruments -
Segfault
int i;
scanf(“%d”, i);
Scanf tries to do something like
*i = value // seg fault here
Segfault occurs in scanf, although the reason is
call to scanf

Note that this is basically a dangling pointer
dereference which took place inside scanf()
Guidelines to avoid segfaults
Always initialize pointers to NULL

This will not avoid segfaults, but may lead to early detection of a problem

While accessing arrays, make sure that array index is valid


Never return address of local variable of a function


DO NOT IGNORE compiler's warnings


Compilers often warn about potential dangling references, type conversions


which have a potential for segfaults


Make sure that you rewrite code to remove all warnings

Use “-Wall” option with gcc. > cc -Wall program.c -o program



gcc -Wall enables all compiler's warning messages. This option should always
be used, in order to generate better code.

You might also like