Memory
Basic Pointers.
What is a pointer?
A pointer is a reference to a value or location in memory. The varible the pointer refers to is known as the pointee.
int x = 3;
int* ptr = &x;
Dereference
A dereference operation can be performed on a pointer to get its value
printf("%d", *ptr);
The NULL pointer
The constant null is a special pointer that encapsulates the idea of “points to nothing”. NULL can play the roll as a boolean false in C.
Pointer Assingment
Assiging one pointer to anotherm akes them the same thing.
int num = 710;
int* ptr = #
int* ptr2 = ptr;
ptr == ptr2 // True
Two pointers refering to a single pointee are said to be sharing. Sharing is often the main goal of pointer manipulation. It can provide efficient facilities for communication between programs.
Shallow vs Deep copying
Sharing can enable communcation between two functions. A shallow copy is when the reference is passed and it is a shared by the calling function and the callee. A deep copy is when a copy is sent over so each function has their own.
Bad Pointers
When a pointer is first allocated it does not have a pointee, a pointer without a pointee is considered a bad pointers. Derefencing a null pointer can lead to very erractic program behavior. It has the potential to corrupt a random point of memory which can lead to uninsightful errors down the road.
- The pointer must be allocated
- The pointer must be allocation
- The pointer must point to the pointee
A bad pointer can be expressed with XXX in a box p [ XXX ]
Pointer Syntax
int* int pointer
float* float pointer
struct fraction* pointer to struct fraction
struct fraction** pointer to struct fraction*
void PointerTest() {
int a = 1;
int b = 2;
int c = 3;
int* p;
int* q;
}
Map:
a [ 1 ] p [ XXX ]
b [ 2 ] q [ XXX ]
c [ 3 ]
...
p = &a;
q = &a;
Map:
a [ 1 ] <------ p [ ]
b [ 2 ] <------ q [ ]
c [ 3 ]
c = *p;
p = q;
*p = 13;
Map:
a [ 1 ]
b [ 13 ] <----------- p [] q []
c [ 1 ]
Bad Pointer Code Example
void BadPointer() {
int* p;
*p = 42; // This dereference is a runtime error
}
Pointer Rules
- A pointer stores a reference to a pointee, The pointee contains the value
- The dereference operation on a pointer accesses its pointee. A pointer may be dereferences after being assigned, most bugs involve violating this rule
- Allocating a pointer does not automatically assign it to refer to a pointee.
- Assignment between two pointers makes them refer to the same pointee, introducing sharing
How are pointers implement in the machine
Pointers are simply just integers that contain the numeric addreess to an area of memory. The dereference operation just looks at that address
Local Memory
Variables represent storage space in the computer’s memory. A variable is considered to be allocated after it is given a place in memory. When a variable’s memory is reclaimed by the system it is said to be deallocated
Variables allocated in a function will only exist so long as that function is still running – commonly refered to as variable lifetime. When a function exits, its local storage is deallocated.
Local storage process
- When a function is called memory is allocated for all of its locals – When the { is hit all of the locats are allocated.
- The memory for the locals continues to be allocated so long as the thread of control is within the owning function
- When the function finishes and exits, the locals are deallocated.
Locals example
[Dis]/Advantages of locals
locals are great because they are convenient, efficient, and passed by value so there is no worry about conflicting resources
locals are bad because they have restricted communication and a short lifetime.
More on locals
Locals are automatic because allocation and deallocation are handles by the function call mechanism, These variables are refered to as stack variables.
When a function exits, a pointer to variable allocated in it will be deallocated.
Passing by reference
One can pass an arugment by reference by using & to pass a pointer to a callee function. Noe the & must be used by the caller.
Double pointers can be used to manipulate collections of pointers.
Heap Memory
C gives the facilities to allocate and deallocate dynamic heap memory.
Heap memories lifetime and size are defined by the programmer.
The heap memory does not operate automatically and conveniently the way local memory does.
What does the heap look like?
The heap is large area of memory avaliable for use by the programmer. The program requests this will heap allocation functions malloc()
, can resize with realloc()
and can free up the memory free()
.
Main heap features
- The heap is an area of memory avaliable to allocate areas of memory for the program
- Initially all of the heap is free
- The heap may be of a fixed size, or it may appear to be of a fixed but extremely large size. It is possible for the heap to be fulled
- The allocation function request a block in the heap of a paricular size. Its location in the heap is fixed. When it is allocated and uninitalize the values are random.
- After the deallocation the program must consider the pointer as “bad”
Memory leaks
Is some memory is heap allocated but never deallocated is only a problem if the program runs for a long time. If there is no proper deallocation the heap will eventually get filled up and either crash or slow down due to memory learks.
Malloc
void* malloc(size_t size);
Returns a contiguous block of memory of the given size in the heap. malloc() returns a point to the heap bblock or NULL if it fails. size_t is a unsigned long.
Free
void free(void* block);
Frees a block allocated by malloc()4
Realloc
void* realloc(void* block, size_t size);
Takes an existing heap block and tries to relocate it to a heap block of the given size whether larger or smaller.
Dynamic Arrays
One can create a dynamic array with malloc()
int* b = (int*) malloc(sizeof(int) * 1000);
is equivalent to
int b[1000];
You can even change the size of the array with
b = realloc(b, sizeof(int) * 2000);
Which is equivalent to
int b[2000];