系统级程序设计笔记(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 变量,内存???

  • [简答题] 为什么要使用动态内存分配?

    1

    1

    1

    • 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

1


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

1

Memory Leaks

1

  • 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

实例应用

为C语言的动态内存分配添加出错预警.