Transcript Document

Overview
• Working directly with memory locations is beneficial. In
C, pointers allow you to:
• change values passed as arguments to functions
• work directly with memory that has been dynamically
allocated
• efficiently work with complex data types such as large
structure, linked lists, and arrays.
Introduction to Pointers
• Definition: A pointer is a variable whose content is the
address of another variable.
• The size of the pointer variable must be n bits where 2n
bytes is the size of the address space.
• On our current Intel x86 machines, the amount of space
required to hold a pointer variable is 8 bytes and is not
related to the size of the entity to which it points.
Introduction to Pointers
• To declare a pointer in a program just use the type it points
to followed by *.
int
*a;
short
*b;
unsigned char *c;
Introduction to Pointers
• You can declare a pointer and have it point to (make its
value be) that location in memory for the variable called x
as follows:
int x = 7; // variable x of type integer
int *ptr; // a pointer to an integer variable
ptr = &x; // pointer points to memory location x
• The asterisk (*) in the declaration denotes that ptr is to be a
pointer and the int indicates the type of data to which ptr will
point.
• The address operator (&) in the third line refers to the
address of x.
Introduction to Pointers
What is physically going in RAM?
int x = 7;
int *ptr = &x;
20000
7
x
90000
20000
ptr
7
*
x
ptr
Dereferencing a Pointer
• If you want to change the value that ptr is pointing to, you
can write the following:
*ptr = 25;
same effect as,
x = 25;
• In either case, the value at that memory location was
changed to 25.
• Remember: A direct assignment to a pointer variable will
change the address of the pointer, not the value at the
address that it is pointing to.
• A pointer directly refers to the address of a variable, and
the * operator on the pointer will allow you to change the
value at the location of that address via dereferencing
(indirection).
Initialization of pointers
Like all variables, pointers must be initialized before they are
used.
/* p17.c */
/* Example of a common error: failure to intialize */
/* a pointer before using it.. This program is */
/* is FATALLY flawed.... */
main()
{
int* ptr;
*ptr = 99;
printf("val of *ptr = %d and ptr is %p \n", *ptr, ptr);
}
But unfortunately, on Linux this program appears to work!
class/210/examples ==> p17
val of *ptr = 99 and ptr is 0x40015360
Initialization of pointers
The program appears to work because the address
0x40015360 just happens to be a legal address in the address
space of this program. Unfortunately, it may be the address of
some other variable whose value is now 99!!!
This situation is commonly referred to as a loose pointer and
bugs such as these may be very hard to find.
Initialization of Pointers
We can convert the bug from latent to active by changing the
location of the variable ptr.
Here we move it down the stack by declaring an array of size
200.
class/2100/examples ==> cat p18.c
/* p17.c */
/* Example of a common error: failure to intialize */
/* a pointer before using it */
main()
{
int a[200]; // force ptr to live down in uninit turf
int* ptr;
printf("val of ptr is %p \n", ptr);
*ptr = 99;
printf("val of *ptr = %d and ptr is %p \n", *ptr, ptr);
}
Initialization of Pointers
class/2100/examples ==> p18
val of ptr is (nil)
class/2100/examples ==>
Note that in this case the second printf() is not reached
because the program segfaulted and died when it illegally
attempted to assign the value 99 to memory location 0 (nil).
Minimizing latent loose pointer problems
Never declare a pointer without initializing it in the
declaration.
int *ptr = NULL;
Stack and Heap Memory
• Stack resident variables include:
– Parameters passed to functions
– Variables declared inside basic blocks that are not
declared static.
• For stack resident variables, the size of the variables
must be known at compile time.
• Heap resident variables include:
– Variables declared outside of all functions.
– Variables declared inside basic building blocks that
are declared static.
– Memory areas dynamically allocated at run time with
malloc().
Correct use of the pointer
In the C language, variables that are declared within any basic
block are allocated on the runtime stack at the time the basic
block is activated.
/* p19.c */
main() Addresses of y and ptr
{
int y;
int* ptr;
static int a;
ptr = &y;
// assign the address of y to the pointer
*ptr = 99; // assign 99 to what the pointer points to (y)
printf("y = %d ptr = %p addr of ptr = %p \n", y, ptr, &ptr);
ptr = &a;
}
printf("The address of a is %p \n", ptr);
Correct use of the pointer
class/210/examples ==> p17
y = 99 ptr = 0xbffff894 addr of ptr = 0xbffff890
The address of a is 0x804958c
Note that a is heap resident and has an address far removed
from the stack resident y and ptr.
Correct use of the pointer
class/210/examples ==> p17
y = 99 ptr = 0xbffff894 addr of ptr = 0xbffff890
The address of a is 0x804958c
Note that a is heap resident and has an address far removed
from the stack resident y and ptr.