C语言熟练操作内存

简介: C语言熟练操作内存

嵌入式编程之内存操作


数据指针


在嵌入式系统编程中,经常会对特定的内存单元进行读写操作。在汇编中有对应的MOV指令,而在C/C++以及其他高级语言中基本没有直接操作绝对地址的能力。而在嵌入式系统的实际开发调试过程中,大多情况会借助C语言指针多具备的对绝对地址单元内容的读写能力。

直接使用指针操作内存,主要分为以下几种情况:


某I/O芯片被定位在CPU的存储空间而非I/O空间,而且寄存器对应的是特定的地址

两个CPU之间以双端口RAM进行通信,CPU需要在双端口RAM的特定单元(mail box)书写内容以在对方CPU产生中断。

读写ROM或FLASH的特定单元所烧录的汉字或英文字模

< 在绝对地址0x01写入10
unsigned char *p = (unsigned char *)0x01;
*p = 10;


使用绝对地址时,需要注意指针自增自减的结果取决于指针指向的数据类型。


int *p = (int *)0x01;


p++的结果为:p = p + sizeof(int);p–的结果为:p = p - sizeof(int);

cpu以字节为单位编址,而C语言指针以指向的数据类型长度作为自增自减


函数指针


C 语言中函数名直接对应于函数生成的指令代码在内存中的地址,因此函数名可以直接赋给指向函数的指针


调用函数实际上等同于"调转指令+参数传递处理+回归位置入栈",本质上最核心的操作是将函数生成的目标代码的首地址赋给CPU 的PC 寄存器


因为函数调用的本质是跳转到某一个地址单元的code 去执行,所以可以"调用"一个根本就不存在的函数实体

typedef void (*lpFunction) ( ); < 定义一个无参数、无返回类型的函数指针类型
< 定义一个函数指针,指向CPU 启动后所执行第一条指令的位置
lpFunction lpReset = (lpFunction)0xF000FFF0;
lpReset();   < 函数调用


《微型计算机原理》中讲到,186 CPU 启动后跳转至绝对地址0xFFFF0,该地址对应到C语言中为上述例子中的0xF000FFF0,其中0xF000为段地址,0xFFF0为段内偏移。


在上述例子中,根本没有定义函数,但是却能够执行lpReset()函数的调用,它实际的作用为"软重启",使程序跳转到CPU启动后第一条要执行的执行位置。


动态申请内存


在嵌入式系统中动态内存申请存在比一般系统编程时更严格的要求,这是因为嵌入式系统的内存空间往往是十分有限的,不经意的内存泄露会很快导致系统的崩溃。

因此,maloc和free一般要保证成对出现。


char *Function(void) {
  char *p = NULL;
  p = (char *)malloc(sizeof(char));
  ...
  return p;
}
void main() {
  char *q = Function();
  ...
  free(q);
}

上面这个例子明显是不合理的,因为它违反了"谁申请,就由谁释放"的原则。若程序不满足这个原则的话,会导致代码的耦合度增大,使用者需要在调用的时候知道Function()函数中的具体实现。


正确做法应该如下:

void Function(char*p) {
  ...
}
void main() {
  char *q = malloc(sizeof(char));
  ...
  Function(q);
  ...
  free(q);
}


相关文章
|
1月前
|
程序员 C语言
C语言库函数 — 内存函数(含模拟实现内存函数)
C语言库函数 — 内存函数(含模拟实现内存函数)
33 0
|
16天前
|
C语言
C语言:内存函数(memcpy memmove memset memcmp使用)
C语言:内存函数(memcpy memmove memset memcmp使用)
|
2天前
|
存储 程序员 编译器
C语言:动态内存管理
C语言:动态内存管理
9 1
|
2天前
|
存储 编译器 程序员
C语言:数据在内存中的存储
C语言:数据在内存中的存储
9 2
|
2天前
|
存储 编译器 C语言
C语言:字符函数 & 字符串函数 & 内存函数
C语言:字符函数 & 字符串函数 & 内存函数
10 2
|
10天前
|
存储 C语言 开发者
【C言专栏】C 语言实现动态内存分配
【4月更文挑战第30天】C语言中的动态内存分配允许程序运行时按需分配内存,提供处理未知数据量的灵活性。这涉及`malloc()`, `calloc()`, `realloc()`, 和 `free()`四个标准库函数。`malloc()`分配指定大小的内存,`calloc()`同时初始化为零,`realloc()`调整内存大小,而`free()`释放内存。开发者需谨慎处理内存泄漏和指针使用,确保程序的稳定性和性能。动态内存分配是C语言中的重要技能,但也需要良好的内存管理实践。
|
11天前
|
存储 编译器 C语言
C语言进阶第十课 --------文件的操作-1
C语言进阶第十课 --------文件的操作
|
11天前
|
存储 程序员 C语言
C语言进阶第九课 --------动态内存管理-2
C语言进阶第九课 --------动态内存管理
|
11天前
|
编译器 C语言
C语言进阶第九课 --------动态内存管理-1
C语言进阶第九课 --------动态内存管理
|
16天前
|
程序员 编译器 C语言
C语言知识:动态内存管理(malloc free calloc realloc)
C语言知识:动态内存管理(malloc free calloc realloc)