系统级程序设计笔记(4)
Memory Layout and Allocation
前言
本篇博客整理了系统级程序设计课程中的lecture5
.
相关材料见:SLP-Notes
待更新
- static
- 库函数的详细定义
- Memory Bugs
Several Uses of Memory
Static Allocation
-
Static Allocation
- happen at compile time and link time
- exist at a fixed address throughout the execution of the program
-
Static Allocation vs. C++ static Declarations
-
Static Allocation
//a statically allocated variable int my_var[128]; int my_var[128]; static bool my_var_initialized = false; int my_fn(int x){ if (my_var_initialized) return; my_var_initialized = true; for(int i=0;i<128;i++) my_var[i] = 0; }
-
C++ static Declarations
//a statically allocated variable int my_var[128]; int my_var[128]; int my_fn(int x){ static bool my_var_initialized = false; if (my_var_initialized) return; my_var_initialized = true; for(int i=0;i<128;i++) my_var[i] = 0; }
-
-
static 变量,内存???
-
[简答题] 为什么要使用动态内存分配?
- Precautions For Static Allocation
- Good reasons to use D.A. of variables
Dynamic Allocation
-
A Function Call Using the Stack
- Activation Record or Stack Frame
- TOS = Top of Stack
- Frame = Activation Record Base
- PC = Program Counter
-
函数调用的过程,详见[深入理解C语言的函数调用过程] .
Eg:
int find(char *str, char *pat) { int i, j, str_max, pat_max; pat_max = strlen(pat); str_max = strlen(str) - pat_max; for (i = 0; i < str_max; i++){ for (j = 0; j < pat_max; j++){ if (str[i + j] != pat[j]) break; } // Did loop complete? If so, we found a match. if (j == pat_max) return i; } return -1; } void main() { printf("find(\"this is a test\", \"is\") -> %d\n", find("this is a test", "is")); printf("find(\"this is a test\", \"IS\" -> %d\n", find("this is a test", "IS")); getchar(); }
P31 ???
Heap Allocation
- Common Memory Bugs
- Forget to free memory
- Memory leak
- Dangling pointer problem
- C++ never tries to debug the above
- Explicit vs. Implicit
Program Memory Layout
Heap memory management
库函数
<stdlib.h>
malloc()
calloc()
realloc()
free()
<unistd.h>
sbrk()
Allocator
[简答题]
-
分配器的要求和目标
教材P590
-
碎片
教材P591
-
策略选择
教材P592
-
实例应用:隐式空闲链表
- 放置已分配的块
- 分割空闲块
- 获取额外的堆内存
- 合并空闲块
- 带边界标记的合并
-
实例应用:一个简单的分配器
Memory Bugs
Code Examples
-
size_t
无符号数
-
P94-96???
-
Off-by-One Bug
#define array_size 100 int *a = (int *) malloc(sizeof(int *) * array_size); for (int i = 0; i <= array_size; i++) a[i] = NULL;
-
Allocate too less memory
#define array_size 100 int *a = (int *) malloc(array_size); a[99] = 0; // this overwrites memory beyond the block
-
Data will be overwritten due to Too Less Memory allocated
char *heapify_string(char *s) { int len = strlen(s); char *new_s = (char *) malloc(len); strcpy(new_s, s); return new_s; }
-
Referencing a Pointer instead of the Object it points to
void dec_positive(int *a) { *a--; // decrement the integer if (*a < 0) *a = 0; // make sure a is positive }
-
Never return a Local Pointer
int *ptr_to_zero() { int i = 0; return &i; }
-
Eg
char q[] = "do not overflow"; char r[] = " memory"; char s[16]; strcpy(s, q); strcat(s, r);
-
Eg
strcat("don't overflow", "memory");
Twice Free
Memory Leaks
-
Eg1
void my_function(char *msg) { // allocate space for a string char *full_msg = (char *) malloc(strlen(msg) + 100); strcpy(full_msg, "The following error was encountered: "); strcat(full_msg, msg); if (!display(full_msg)) return; free(full_msg); }
-
Eg2
typedef struct { char *name; int age; char *address; int phone; } Person; void my_function() { Person *p = (Person *) malloc(sizeof(Person)); p->name = (char *) malloc(128); p->address = (char *) malloc(128); free(p); }
-
Eg3
指导书分章Unit3 练习2