Cortex-M的动态分配与指针 指针取地址/ 解引用*类型与步长STM32 是 32 位单片机任何指针变量无论指向char还是double本身都占用4 个字节32bit的 RAM用来存放一个 32 位的内存地址。指针1加的字节数是根据指向的类型决定的char *p1; // p1 1 移动 1 字节 short *p2; // p2 1 移动 2 字节 int *p3; // p3 1 移动 4 字节 uint32_t *p4; // p4 1 移动 4 字节 void *p5; // 通用指针不能直接不知道步长这些指针的大小都是4字节移动的步长不同。数组与int arr[5]; arr; // 代表数组首元素地址类型 int* arr; // 代表整个数组的地址类型 int (*)[5] arr 1 // 移动 4 字节指向 arr[1] arr 1 // 移动 20 字节跳过整个数组指向数组末尾之后const与volatileconst在*左边修饰的是指向的内容const在*右边修饰的是指针本身const int *p1; // 指向的内容只读不能改 *p1但 p1 可以指向别处 int * const p2; // 指针本身只读不能改指向但内容可以改 const int * const p3;// 指针和内容都只读volatile不被编译优化。volatile uint32_t *reg (uint32_t*)0x40020000; // 硬件寄存器地址 // 每次读取 *reg编译器都会去读物理地址而不是用缓存的值多级指针与函数指针二级指针修改指针的值把指针变量看成一个完整的变量void allocate_memory(void **ptr) { // ptr 指向外部指针变量的地址 *ptr pvPortMalloc(100); // 修改外部指针指向新分配的内存 } int *buf NULL; allocate_memory((void**)buf); // 传入指针的地址函数指针void (*task_func)(void *); // 定义一个函数指针变量 task_func StartDefaultTask; // 赋值 task_func(NULL); // 调用 // 更复杂的例子指向返回 int参数为两个 int 的函数指针 int (*calculator)(int, int) add; int result calculator(3, 4);mallocvoid Task_A(void *arg) { int local_val 5; // 这个变量在 Task_A 的栈上 osMessageQueuePut(queue, local_val, 0, 0); // 传递地址 // 函数返回后栈帧释放这块地址可能被其他任务覆盖 }local_val这个变量创建在了进程对应的栈上会被后续的内容覆盖所以要么放在静态区(只有一个进程更改这个值)要么放在堆区。使用pvProtMalloc动态分配内存int *pData (int*)pvPortMalloc(100 * sizeof(int)); // 申请400字节 // 2. 检查是否分配成功 if (pData ! NULL) { // 3. 使用这块内存 pData[0] 123; pData[99] 456; // 4. 使用完毕后释放内存 vPortFree(pData); // 5.将指针置空防止误用 pData NULL; }静态存储区存放全局变量和static修饰的变量。栈存放进程内部创建的变量。堆存放动态分配的变量。常量区:存放字符串常量。