CS61C C Note

揭示C语言的本质

  1. Array在传递给函数时记得必须要一并传递Array的大小,因为在函数内使用sizeof会得到不正确的结果。
  2. Array in C don’t know their size.
  3. 数组名不是一个变量。
  4. Struct Alignment.
  5. A String in C is just an array of characters.
  6. String end. Last character is followed by a 0 byte(‘\0’)(a.k.a null terminator).
  7. strlen() return the length of string(not including null term).
  8. Pointer Arithmetic, Pointer+1实际上是加指针指向的类型的大小sizeof(*p). Pointer arithmetic moves the pointer by the
    size of the thing it’s pointing to.
  9. 注意postfixal++的优先级要大于dereference(*), 注意这两种区别*p++,先将p和后置++捆绑,但是在解引用之后生效,即增以p=p+1。(*p)++表示,先将p和*捆绑,再将解引用后的值++, 即(*p) = (*p) + 1.
  10. 声明一个指针如果未初始化,则随机指向任何一个地址garbage,这在dereference时会发生ACV(如果地址为系统地址)。
  11. dot notation & arrow notationss
  12. pointers to pointers, 还有一点需要注意。如果传的参数不是当前类型本身的地址,则在函数中改变的值不会对全局造成影响,比如:类型本身是指针就需要传递指针的指针才能改变本身的值。
  13. Stack frame, which contains location of caller function(调用函数的入口地址)、function arguments(函数参数)、Space for local variables(局部变量所需的空间). Actually in xv6, it contains the additional part of previous stack frame pointer.
  14. Stack pointer 为最低的(current)Stack frame.
  15. 注意从局部变量返回地址,这个地址在接下来主函数中解引用会出现错误的值,因为栈帧(stack frame)很可能会被覆盖(over write)。印象中Effective cpp书中只是提到这种情况是危险的但并未说清楚其中的原理。So never return pointers to local variable from function.
  16. Static Data: place for variables that persist. 静态数据会在程序执行的整个过程中持续存在。
  17. String literal字符串字面量同样也是静态数据,比如: char* str = "hi", 为一个字符指针指向用引号括起来的字符串。切记不要误用为char str[] = "hi",它会将数据保存到栈(stack)中而不是Static Data区域。
  18. String literal是不能被更改的左值。
  19. Static Data由两种类型组成,一种是Read-only, 比如说String literal; 一种是Read-Write, 比如说Global variable.
  20. CodeRead-only Data,存放machine code.
  21. 地址大小即为指针的大小,取决于Architecture.
  22. Endianness, Big Endian or Little Endian, which just are used in Memory.
  23. sizeof(type/var)函数输出类型的字节大小。
  24. malloc(n)函数,分配n个bytes连续的未初始化的虚存,返回分配块的起始地址(void*类型)。搭配typecaset和sizeof使用,case: int *p = (int *) malloc(n*sizeof(int));, 注意如果为字符串(字符数组)分配空间size则需要+1,为null terminator分配一个location.
  25. calloc(nmember, size)malloc一致, 只多了一步初始化为0. nmember为成员的数量,size为每个成员的大小。
  26. realloc(ptr, size), ptrmalloccalloc返回的指针,size为需要改变的所需要的大小(同malloc),会复制起始地址为ptr的内容。且可能会移动地址,或者保持在ptr原来的地址不变。
  27. free(p)函数,p必须为最开始分配时的起始地址,否则会抛出异常,因此对p++操作是不明智的。注意free的释放顺序,应该最后释放,否则可能会double free。
  28. Memory Error: Segmentation Error、Bus Error.
  29. strcpy()的修订版本strncpy保证dst有足够的空间供src来copy.
  30. Rule of Thumb(经验法则): Malloc的数量超过free意味着内存泄漏;潜在的内存泄漏:改变指针。
  31. free() adds block to the list, combines with adjacent free blocks; malloc() searches free list for block large enough to meet request
  32. Choose block in malloc(): Best-fit, First-fit, Next-fit.