C 指针与内存管理

动态存储分配

内存分配函数

<stdlib.h> 头文件中的

  1. malloc 分配内存,不初始化
  2. calloc 分配内存,并清零
  3. realloc 调制分配内存大小

内存分配函数返回 void * 类型,本质上只是内存地址

空指针

内存分配函数有可能返回空指针 NULL ,使用空指针会导致程序崩溃,所以要判断指针是否为空指针。

c语言中空指针为假,非空指针都为真。

常用如下方式进行判断

if (p == NULL) {
                ...;
}

malloc

原型 void *malloc(size_t size);

惯用法

double *p = malloc(N * sizeof(*p));

calloc

原型 void *calloc(size_t nmemb, size_t size); 分配 nmemb 个元素,每个元素大小为 size.

realloc

原型 void *realloc(void *ptr, size_t size);

  1. 扩展时,不会对新加进来的做初始化
  2. 扩展失败时,返回空指针并不影响原来的元素
  3. 传入空指针时,与 malloc 行为一致
  4. 第二个参数是0时,释放内存

一旦 realloc 返回,记得更新之前的所有指针,因为可能会把元素都复制到了别的地址

释放内存 free

原型 void free(void *ptr);

声明

声明说明符

  1. 存储类型。包括 auto, static, extern, register ,只能有一个,必须放在最前面
  2. 类型限定符。包括 const, volatile, restrict(C99) ,可以有一个或多个
  3. 类型说明符。包括基本类型、结构、枚举和联合
  4. 函数说明符。包括 inline(C99) ,只用于函数声明

解释复杂的声明符

  1. 始终从内往外读声明符
  2. []和()优先于 * ,即 *p[] 是数组, *f() 是函数

关键字

关键字 存储类别 存储期 作用域 链接 声明方式
可选 (auto) 自动 自动 块内
register 寄存器 自动 块内
静态外部链接 静态 文件 外部 函数外
static 静态内部链接 静态 文件 内部 函数外
static 静态无链接 静态 块内
extern 外部        
_Thread_local          
const 不可变        
inline          
volatile 代理,可由其它程序改变        
restrict 限定唯一的指针        
_Atomic          
  1. 好的设计不应该使用文件作用域的变量
  2. auto 关键字用于明确显示使用了与外部同名的变量名,与 c++ 中的完全不同,不建议使用
  3. 函数的默认类别是 extern 除非使用了 static 指定为模块私有
  4. static 静态指的是生命周期一直在, const 才是不可变
  5. const 变量只能初始化,不能修改
  6. const float * pf 指针 pf 指向 const float 类型的对象,即对象内容不可变,但指针可以指向其它地址
  7. float const * pf 同上
  8. float * const pf 指针 pf 指向 float 类型的对象,即对象内容可变,但指针不能指向其它地址
  9. const* 前面表示指向的值不能变,在 * 后面表示指针本身不能变
  10. 函数的形参中有 const 表示传递的值不变
  11. restrict 限制指针是指向内存的唯一和初始方式,用于优化

TODO

  1. -Ofast -flto -march=native -funroll-loops -fPIC

评论

Comments powered by Disqus