1 Memory Model
类型 | 描述 | 大小 |
---|---|---|
int | 整形数字 | 4B |
short | 整形数字 | 2B |
long | 整形数字 | 8B |
char | 字符 | 1B |
float | 浮点型 | 4B |
double | 浮点型 | 8B |
void* | 指针 | 4B(32bit) 8B(64bit) |
2 Local Memory Allocation on the Stack
1.声明整型a
,将在内存里分配4字节的空间.
int a = 10;
2.allocation is local, occurring within the scope of the function, and when that function returns the memory is deallocated(当函数返回时,空间被回收(deallocated))
int * plus(int a, int b){
int c = a + b;
return &c; //return a reference to locally declared c,c地址指向的空间内容在函数返回时已经被回收,所以不会有相应的结果
}
int main(int argc, char * argv[]){
int * p = plus(1,2);
printf("%d\n",*p); //dereference return value
//to print an integer
}
plus(1,2) return &c printf("%d\n",*p)
(main) | (main) | (main) | (main)
.---.----. | .---.----. | .---.----. | .---.----.
| p | .-+-X | | p | .-+-X | | p | .-+---. | | p | .-+---.
'---'----' | '---'----' | '---'----' | | '---'----' |
| ------------- | ------------ | | |
| (plus) | (plus) | | |
| .---.---. | .---.---. | | |
| | a | 1 | | | a | 1 | | | |
| |---|---| | |---|---| | | |
| | b | 2 | | | b | 2 | | | |
| |---|---| | |---|---| | | |
| | c | 3 | | | c | 3 | <--' | X--'
| '---'---' | '-------'
c exists locally returning a reference When p is dereferenced
in plus() to c assined to p it points to unallocated memory
2.1 The Stack(栈)
- Another term for local memory allocation is stack allocation because the way programs track execution across functions is based on a stack(栈空间分配主要是处理函数调用)
- LIFO data structure, last-in-first-out
- A stack has two primary functions:
- push : push an item on to the top of the stack
- pop : pop an item off the top of the stack
4.函数和其相关的内存空间(函数内声明的变量)一起 进出stack
int gettwo(){
return 2;
}
int getone(){
return 1;
}
int addonetwo(){
int one = getone();
int two = gettwo();
return one+two;
}
int main(){
int a = addonetwo();
}
program executed .------ top of stack
v
main()
push main | | main() |
| '----------------'
addonetwo()
|
push addonetwo | | addonetwo() |
| | main() |
| '----------------'
getone()
|
| | getone() |
push getone | | addonetwo() |
| | main() |
| '----------------'
return 1
pop | | addonetwo() |
| | main() |
| '----------------'
gettwo()
|
| | gettwo() |
push gettwo | | addonetwo() |
| | main() |
| '----------------'
return 2
pop | | addonetwo() |
| | main() |
| '----------------'
return 1 + 2
pop | | main() |
| '----------------'
program exits
3 Global Memory Allocation on the Heap
Node * node = new Node();
1.The new function performs a dynamic memory allocation in global memory that is not associated with scope of functions or the stack.(new 函数实现了全局的动态分配,和函数内部与栈相区别)
2.It is instead allocating on the heap.(在堆区里分配)
3.1 The heap, malloc() and free()
1.全局内存空间称为heap(堆)
2.Whenever a program needs to allocate memory globally or in a dynamic way, that memory is allocated on the heap, which is shared across the entire program irrespective of function calls.(堆内存在整个程序运行期间被全局共享)
3.In C the new function is called malloc()
// .--- Allocate sizeof(int) number of bytes
// v
int * p = (int *) malloc(sizeof(int));
// ^
// '-- Cast to a integer pointer
4.heap上的内存空间要手动释放,而stack上的系统自动释放
int * p = (int *) malloc(sizeof(int));
//do something with p
free(p); //<-- deallocate p
5.和栈上的返回指针相比较,这个函数就没问题
int * plus(int a, int b){
int *p = (int *) malloc(sizeof(int)); //allocate enough space for
*p = a + b; //for an integer
return p; //return pointer
}
int main(int argc, char * argv[]){
int * p = plus(1,2); //p now references memory on the heap
printf("%d\n",*p);
free(p); //free allocated memory
}
3.2 Memory Leaks and other Memory Violations(内存泄漏)
1.Memory Leaks 内存泄漏
int main(int argc, char * argv[]){
int i, * p;
for(i=0;i>100;i++){
p = (int *) malloc(sizeof(int)); //每次指针都被覆盖,而丢失,无法释放
*p = i;
}
}
2.dangling pointer(悬空指针)
1. free()释放指针指向的内存空间后,该内存空间可被其他程序使用,所以不能再使用该指针
2. 指向内存被释放的指针,指针悬空后要把指针赋值为nullp = NULL;
,而不能再次引用
int main(int argc, char * argv[]){
int *p = (int *) malloc(sizeof(int));
//... code
free(p);
//... code
*p = 10;
}
4 Program Layout: Stack vs. Heap
2^64-1---> .----------------------.
High Addresses | Enviroment |
|----------------------|
| | Functions and variable are declared
| STACK | on the stack.
base pointer -> | - - - - - - - - - - -|
| | |
| v |
: :
. . The stack grows down into unused space
. Empty . while the heap grows up.
. .
. . (other memory maps do occur here, such
. . as dynamic libraries, and different memory
: : alloocat)
| ^ |
| | |
break point -> | - - - - - - - - - - -| Dynamic memory is declared on the heap
| HEAP |
| |
|----------------------|
| BSS | The compiled binary code is down here as
|----------------------| well as static and initialzed data
| Data |
|----------------------|
Low Addresses | Text |
0 -----> '----------------------'
1.At the higher addresses is the stack and at the lower address is the heap.The two memory allocation regions grow into the middle of the address space(这样的实际可以使两者互不干扰)
2.这个布局是虚拟的,非物理的.每个进程都会有这样的布局
4.1 Memory Mapping and Dynamic Libraries
1.between the break point and the base pointer is unallocated memory
2.This region can be memory mapped, which is the process of loading data directly from files into memory.(可以映射文件mmap)
3.Another common use for the middle addresses is the loading of dynamic shared libraries.(可以放动态库)
参考:
https://www.usna.edu/Users/cs/aviv/classes/ic221/s16/lec/08/lec.html#coderef-bad_ref