如何在C语言中将数组分配至特定内存地址?
没问题,这其实是嵌入式开发里挺常见的需求,我来给你详细拆解几种可行的实现方式,你可以根据自己的场景选择:
方法1:运行时拷贝数组到指定地址
这是最通用的方式,不管是PC还是嵌入式系统都能尝试(不过PC上随意指定地址大概率会触发段错误,因为用户空间内存受系统管控)。核心思路是先定义数组,再把数组内容拷贝到目标地址:
#include <string.h> #include <stdio.h> #define TARGET_ADDR 0x20000001 // 你的目标地址 int main() { int inputs[10] = {4, 10, 89}; // 原数组 int *target_ptr = (int *)TARGET_ADDR; // 强制转换地址为int指针 // 把原数组内容拷贝到目标地址 memcpy(target_ptr, inputs, sizeof(inputs)); // 测试访问 printf("第一个元素:%d\n", target_ptr[0]); return 0; }
注意事项:
- 目标地址必须是可写的合法内存区域:如果是嵌入式系统,要确认这个地址属于RAM;PC上用户空间不能直接访问任意物理地址,所以这种方法在PC上基本只能用于学习测试。
- 内存对齐问题:
int类型通常要求4字节对齐(不同架构可能有差异),而0x20000001不是4的倍数,直接访问可能会触发总线错误。建议把地址改成0x20000000这类对齐的地址。
方法2:编译时直接将数组放到指定地址(编译器扩展)
如果是嵌入式开发,想要让数组在编译阶段就直接被分配到指定地址,不需要运行时拷贝,可以用编译器提供的扩展属性。
针对GCC编译器(比如Linux嵌入式、STM32用GCC工具链)
需要结合链接脚本实现:
- 先定义数组时指定自定义段:
// 把数组放到自定义的.my_custom_section段中 int inputs[10] __attribute__((section(".my_custom_section"))) = {4, 10, 89};
- 修改链接脚本,把这个自定义段映射到目标地址:
.my_custom_section 0x20000001 : { *(.my_custom_section) // 匹配所有文件中的.my_custom_section段 }
编译时指定链接脚本即可(比如gcc -T your_script.ld main.c)。
针对ARMCC编译器(比如Keil MDK)
ARMCC提供了更直接的at属性,不需要修改链接脚本:
// 直接指定数组的存储地址 int inputs[10] __attribute__((at(0x20000001))) = {4, 10, 89};
编译后数组会直接被放在0x20000001地址处。
方法3:用绝对指针直接映射地址
如果你不需要预先初始化数组,而是想直接通过指针操作指定地址的内存,可以直接定义一个指向目标地址的指针:
#include <stdio.h> #define TARGET_ADDR 0x20000001 // 定义一个指向目标地址的常量指针(防止指针被意外修改) int *const inputs = (int *)TARGET_ADDR; int main() { // 手动初始化数组元素 inputs[0] = 4; inputs[1] = 10; inputs[2] = 89; // 剩下的元素可以根据需要赋值,默认是内存原有值(可能是随机的) printf("第一个元素:%d\n", inputs[0]); return 0; }
注意事项:同样要注意内存对齐和地址合法性问题,而且这种方式下数组的初始化必须在运行时完成。
内容的提问来源于stack exchange,提问作者Polymorphism
相关产品推荐
相关产品推荐

