CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
C 语言入门/课时/指针与内存
RawBlame
课时目录12 节

C 语言入门

  1. 01C 是什么
  2. 02类型与变量
  3. 03控制流与运算符
  4. 04函数
  5. 05指针与内存
  6. 06数组与字符串
  7. 07结构体与联合体
  8. 08预处理器
  9. 09编译与构建
  10. 10并发与进程
  11. 11调试与测试
  12. 12综合练习

指针与内存

栈/堆、malloc/free、生命周期。

40 分钟

指针与内存

指针是 C 的灵魂,也是风险来源。对照 /roadmaps/c,本课讲解栈与堆、malloc/free 及指针的生命周期——C 区别于 Java 的核心。

学习目标

  • 理解指针、取地址与解引用
  • 区分栈变量与堆分配
  • 正确使用 malloc、calloc、realloc、free
  • 避免悬空指针与重复释放

核心概念

栈指针与堆分配

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void swap_int(int *a, int *b) {
    int tmp = *a;
    *a = *b;
    *b = tmp;
}

char *make_greeting(const char *name) {
    size_t len = strlen(name) + 8;
    char *buf = malloc(len);
    if (buf == NULL) return NULL;
    snprintf(buf, len, "Hi, %s!", name);
    return buf;   /* 调用方负责 free */
}

int main(void) {
    int x = 10, y = 20;
    int *px = &x;

    printf("x=%d, *px=%d\n", x, *px);
    swap_int(&x, &y);
    printf("after swap: x=%d y=%d\n", x, y);

    /* 堆分配 */
    int *arr = calloc(5, sizeof(int));
    if (arr == NULL) return 1;
    for (int i = 0; i < 5; i++) arr[i] = i * i;

    arr = realloc(arr, 8 * sizeof(int));
    if (arr == NULL) return 1;
    arr[5] = 25;

    char *msg = make_greeting("CodeRoadMap");
    if (msg) {
        puts(msg);
        free(msg);
        msg = NULL;   /* 避免悬空指针 */
    }

    free(arr);
    arr = NULL;

    int stack_val = 42;
    int *danger = &stack_val;
    printf("stack pointer ok: %d\n", *danger);
    /* 切勿 return 栈变量地址给调用方 */

    return 0;
}

生命周期对照

存储分配释放典型用途
栈自动离开作用域局部变量、小对象
堆malloc 等free动态大小、跨函数存活
静态程序加载程序结束全局变量、static

规则:每个 malloc 对应一次 free;释放后不再解引用;NULL 检查失败返回值。

与 C++/Java 对照

特性CC++Java
显式指针核心有(+ 引用)无(仅对象引用)
堆管理malloc/free/、智能指针
new
delete
GC
地址运算p + 1支持不支持
空指针NULLnullptrnull
内存泄漏手动排查RAII 缓解GC 兜底

Java 引用不暴露地址;C 指针可算术运算,是数组与底层 API 的基础。C++ 智能指针类似「确定性 GC」。

练习

  • 用指针实现 void fill(int *arr, int n, int value)
  • 动态创建含 n 个元素的数组,读入并求平均值,记得 free
  • 说明「返回局部变量地址」为何危险
  • 用 Valgrind 或 ASan 检测故意泄漏的 malloc(见 debug 课)

小结

指针管地址,malloc 管堆;谁分配谁释放。 下一课学习数组与字符串。

加载本节练习…
← 上一课函数下一课 →数组与字符串