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