08 内存分配和程序内存布局

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(栈)

  1. Another term for local memory allocation is stack allocation because the way programs track execution across functions is based on a stack(栈空间分配主要是处理函数调用)
  2. LIFO data structure, last-in-first-out
  3. A stack has two primary functions:
    1. push : push an item on to the top of the stack
    2. 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值