L04 C Intro Pointer Memory Manage
L04 C Intro Pointer Memory Manage
Computer Architecture
C Pointers & Array
Instructors:
Siting Liu & Chundong W ng
Course website: https://to st-l b.sist.sh ngh itech.edu.cn/courses/CS110@Sh ngh iTech/
Spring-2023/index.html
School of Inform tion Science nd Technology (SIST)
Sh ngh iTech University
2023/2/6
a
a
a
a
a
a
a
a
a
a
a
Outline
• Pointer
• Array
• Memory Management
2
Address vs. Value
• Consider memory to be a single huge array
…
Memory
… … … 0x9a 4
0x78 0x56 0x34 0x12
3 2 1 0
3
Pointers
• An address refers to a particular Memory
…
4 p
Variable X
… … … 0x9a 4
0x78 0x56 0x34 0x12
3 2 1 0
4
Pointer Syntax
• int *p; Memory
…
p x 3
*p = 5; p x 5
7
Pointers and Parameter Passing
y remains equal to 3
8
Pointers and Parameter Passing
add_one(&y);
y is now equal to 4
9
Types of Pointers
10
More C Pointer Dangers
• Declaring a pointer just allocates space to hold the
pointer – it does not allocate the thing being pointed to!
• Local variables in C are not initialized, they may contain
anything (a.k.a. “garbage”)
• What does the following code do?
g in
r kin
void f() w o t s
ve n en
{ o t e o n m
N nvir
int *ptr; e e
Unde ined Behavior *ptr = 5;som
}
11
f
Pointers and Structures
typedef struct { /* dot notation */
int x; int h = p1.x;
int y; p2.y = p1.y;
} Point;
/* arrow notation */
Point p1; int h = paddr->x;
Point p2; int h = (*paddr).x;
Point *paddr;
/* This works too */
p1 = {1,2}; p1 = p2;
12
Pointers in C
• Why use pointers?
– If we want to pass a large struct or array, it’s easier/faster/etc. to
pass a pointer than the whole thing
– In general, pointers allow cleaner, more compact code
• So what are the drawbacks?
– Pointers are probably the single largest source of bugs in C, so
be careful anytime you deal with them
• Most problematic with dynamic memory management—
coming up soon
• Dangling references and memory leaks
13
Why Pointers in C?
• At time C was invented (early 1970s), compilers often didn’t
produce ef icient code
– Computers 100,000 times faster today, compilers better
• C designed to let programmer say what they want code to do
without compiler getting in way
– Even give compilers hints which registers to use!
• Today’s compilers produce much better code, so may not
need to use pointers in application code
• Low-level system code still needs low-level access via pointers
14
f
Course Info
• HW1 due today! HW2 will be available very soon (see piazza
& course webpage). Lab 2 will be available this Friday.
• Pointer
• Array
• Memory Management
16
C Arrays
• Declaration:
int ar[2];
declares a 2-element integer array: just a block of memory
• Must specify size (or provide info. that can infer the size)
17
C Strings
• String in C is just an array of characters
char string[] = "abc";
• How do you tell how long a string is?
– Last character is followed by a ‘\0’ (NULL) byte
(a.k.a. “null terminator”) (RTFM)
Finally, the declaration
int strlength(char s[])
{ char s[] = "abc", t[3] = "abc";
int n = 0;
defines ``plain'' char array objects s and t
while (s[n] != 0) whose members are initialized with character
n++; string literals. This declaration is identical to
return n;
} char s[] = { 'a', 'b', 'c', '\0' },
t[] = { 'a', 'b', 'c' };
18
Array Name/Pointer Duality
• Key Concept: Array variable is a “pointer” to the irst (lowest
addressed, i.e., 0th) element
• So, array variables almost identical to pointers
– char *string and char string[] are nearly identical
declarations
– Differ in subtle ways: incrementing, declaration of illed arrays
• Consequences:
– ar is an array variable, but works like a pointer
– ar[0] is the same as *ar
– ar[2] is the same as *(ar+2)
– Can use pointer arithmetic to conveniently access arrays
19
f
f
Array Name/Pointer Duality
• Be really careful!
20
Array Name/Pointer Duality
• Be really careful!
int arr[] = { 3, 5, 6, 7, 9 };
int *p = arr;
int (*p1)[5] = &arr;
int *p2[5];
int *p3(void);
21
Changing a Pointer Argument?
24
f
f
Use De ined Constants
• Array size n; want to access from 0 to n-1, so you should
use counter AND utilize a variable for declaration &
incrementation
– Bad pattern
int i, ar[10];
for(i = 0; i < 10; i++){ ... }
– Better pattern
const int ARRAY_SIZE = 10;
int i, a[ARRAY_SIZE];
for(i = 0; i < ARRAY_SIZE; i++){ ... }
3 2 1 0
• Alignment 32-bit integer
stored in four bytes 26
sizeof() operator
27
f
Pointer Arithmetic
pointer + number pointer – number
e.g., pointer + 1 adds 1 to a pointer, used in array access
29
Arrays and Pointers
int
foo(int array[],
unsigned int size)
{ What does this print
4
… (32-bit address)?
printf(“%d\n”, sizeof(array));
} ... because array is really
Compiler time operator a pointer (and a pointer is
int architecture dependent, but
main(void) likely to be 8 on modern
{ machines!)
int a[10], b[5];
… foo(a, 10)… foo(b, 5) … What does this print
printf(“%d\n”, sizeof(a)); 40
(32-bit int)?
}
30
Arrays and Pointers
31
Concise strlen()
int(long) strlen(char *s)
{ char *p = s;
while (*p++)
; /* Null body of while */
return (p - s - 1);
}
32
Point past end of array?
• Array size n; want to access from 0 to n-1, but test for exit
by comparing to address one element past the last
member of the array
35
Example
% clang -ansi introC_1_1.c -o introC_1_1.out
• argc = 5 /* number arguments */
• argv[0] = "clang",
argv[1] = “-ansi",
argv[2] = “introC_1_1.c”,
argv[3] = “-o”,
argv[4] = “introC_1_1.out”,
• Array of pointers to strings
36
Summary
• “Lowest High-level language”
• Use ANSI C89 in class
• => closest to assembler
• Pointers: powerful but dangerous
37
Summary
• Pointers and arrays are virtually same
• C knows how to increment pointers
• C is an ef icient language, with little protection
• Array bounds not checked
• Variables not automatically initialized
• (Beware) The cost of ef iciency is more overhead for the
programmer.
“C gives you a lot of extra rope but be careful not to
hang yourself with it!”
38
f
f
CS 110
Computer Architecture
C Memory Management
Instructors:
Siting Liu & Chundong W ng
Course website: https://to st-l b.sist.sh ngh itech.edu.cn/courses/CS110@Sh ngh iTech/
Spring-2023/index.html
School of Inform tion Science nd Technology (SIST)
Sh ngh iTech University
2023/2/6
a
a
a
a
a
a
a
a
a
a
a
C Memory Management
• To simplify, assume one program runs at a time
• A program’s address space contains 4 regions:
Memory Address
(32 bits assumed here)
40
f
Where are Variables Allocated?
• If declared outside a function,
allocated in “static” storage
int myGlobal;
• If declared inside function, main() {
allocated on the “stack” int myTemp;
and freed when function
}
returns
• Arguments
• Space for local variables
funcA frame
•
char *stackAddr = \
So your data would no make_buf(); Carving on the
longer exist, and writes can foo();
moving boat to look
overwrite key pointers,
…
} for the sword
causing crashes! 44
Solve with slides to come …
f
Managing the Heap
• The heap is dynamic memory – memory that can be allocated, resized, and
freed during program runtime.
• Useful for persistent memory across function calls
• But biggest source of pointer bugs, memory leaks, …
• Large pool of memory, not allocated in contiguous order
• Back-to-back requests for heap memory could result in blocks very far apart
• C supports four functions for heap management:
• malloc() allocate a block of uninitialized memory
• calloc() allocate a block of zeroed memory
• free() free previously allocated block of memory
• realloc() change size of previously allocated block (might move)
• Read-more: http://web.archive.org/web/20030222051144/http://
home.earthlink.net/~bobbitts/c89.txt section 4.10.3 memory management
functions
45
Managing the Heap
• void *malloc(size_t n):
– Allocate a block of uninitialized memory
– n is an integer, indicating size of allocated memory block in bytes
– size_t is an unsigned integer type big enough to “count” memory bytes
– sizeof returns size of given type in bytes, produces more portable code
– Returns void* pointer to block; NULL return indicates no more memory; always
check for return NULL (if (ip))
– Think of pointer as a handle that describes the allocated block of memory;
Additional control information stored in the heap around the allocated block!
(Including size, etc.)
“Cast” operation, changes type of a variable.
• Examples: Here changes (void *) to (int *)
int *ip1, *ip2;
ip1 = (int *) malloc(sizeof(int));
Ip2 = (int *) malloc(20*sizeof(int)); //allocate an array of 20 ints.
Assuming size of objects can
typedef struct { … } TreeNode; lead to misleading, unportable
TreeNode *tp = (TreeNode *) malloc(sizeof(TreeNode));
code. Use sizeof()!
46
Managing the Heap
• void free(void *p):
– Releases memory allocated by malloc()
– p is pointer containing the address originally returned by malloc()
int *ip;
ip = (int *) malloc(sizeof(int));
... .. ..
free((void*) ip); /* Can you free(ip) after ip++ ? */
47
Managing the Heap
• void *realloc(void *p, size_t size):
– Returns new address of the memory block.
• In doing so, it may need to copy all data to a new location.
realloc(NULL, size); // behaves like malloc
realloc(ptr, 0); // behaves like free, deallocates heap block
48
Summary
• Code, static storage are easy: they never grow or shrink
• Stack space is relatively easy: stack frames are created and destroyed
in last-in, irst-out (LIFO) order, avoid “dangling references"
• Managing the heap is tricky:
• Memory can be allocated/deallocated at any time
• “Memory leak”: If you forget to deallocate memory
• “Use after free”: If you use data after calling free
• “Double free”: If you call free 2x on same memory
49
f
Using Dynamic Memory—Linked List
typedef struct Node node * head = NULL;
head = (node *) malloc(sizeof(node));
{ if(head == NULL){
int val; return 1;
struct Node *next; }
head -> val = 1;
} node; head -> next = NULL;
Create the irst node
The irst node The last node
Ptr to head
50
f
f
Using Dynamic Memory—Iterate
typedef struct Node void print_list(node *head){
{ node * current = head;
while (current != NULL){
int val; printf("%d\t", current -> val);
struct Node *next; current = current -> next;
} node; }
printf("\n");
}
54
Simple Slow Malloc Implementation
Free Space
Malloc library creates linked list of empty blocks (one block initially)
Object 1 Free
First allocation chews up space from start of free space
Free
After many mallocs and frees, have potentially long linked list of odd-sized blocks
Frees link block back onto linked list – might merge with neighboring free space
55
Faster malloc implementations
• Keep separate pools of blocks for different sized objects
• “Buddy allocators” always round up to power-of-2 sized chunks
to simplify inding correct size and merging neighboring blocks:
56
f
Power-of-2 “Buddy Allocator”
free
used
57
Malloc Implementations
58
Agenda
• C Memory Management
• C Bugs
59
Common Memory Problems
60
Using Memory You Don’t Own
• What is wrong with this code?
• Using pointers beyond the range that had been malloc’d
–May look obvious, but what if mem refs had been result of pointer arithmetic that erroneously
took them out of the allocated range?
int *ipr, *ipw;
void ReadMem() {
int i, j;
ipr = (*int) malloc(4 * sizeof(int));
i = *(ipr - 1000); j = *(ipr + 1000);
free(ipr);
}
void WriteMem() {
ipw = (*int) malloc(5 * sizeof(int));
*(ipw - 1000) = 0; *(ipw + 1000) = 0;
free(ipw);
} 61
Faulty Heap Management
void main() {
pi = malloc(4*sizeof(int));
foo();
…
}
62
Faulty Heap Management
void main() {
pi = malloc(4*sizeof(int));
foo(); /* Memory leak: foo leaks it */
…
}
63
Faulty Heap Management
64
Faulty Heap Management
65
Faulty Heap Management
void FreeMemX() {
int fnh = 0;
free(&fnh);
}
void FreeMemY() {
int *fum = malloc(4 * sizeof(int));
free(fum+1);
free(fum);
free(fum);
}
66
Faulty Heap Management
void FreeMemX() {
int fnh = 0;
free(&fnh);
}
void FreeMemY() {
int *fum = malloc(4 * sizeof(int));
free(fum+1);
free(fum);
free(fum);
}
67
Using Memory You Haven’t Allocated
void StringManipulate() {
const char *name = “Safety Critical";
char *str = malloc(10);
strncpy(str, name, 10);
str[10] = '\0';
printf("%s\n", str);
}
68
Using Memory You Haven’t Allocated
void StringManipulate() {
const char *name = “Safety Critical";
char *str = malloc(10);
strncpy(str, name, 10);
str[10] = '\0';
/* Write Beyond Array Bounds */
printf("%s\n", str);
}
69
Using Memory You Don’t Own
• What’s wrong with this code?
70
Using Memory You Don’t Own
• Beyond stack read/write
71
Using Memory You Don’t Own
74
Using Memory You Don’t Own
75
Summary
• All data/program is in memory
– Each memory location has an address to use to refer to it and a
value stored in it
• Pointer is a C version (abstraction) of a data address
– * “follows” a pointer to its value
– & gets the address of a value
– Arrays and strings are implemented as variations on pointers
• C is an ef icient language, but leaves safety to the programmer
– Variables not automatically initialized
– Use pointers with care: they are a common source of bugs in
programs
76
f
Summary
77