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