如何在C编程语言中手动分配指针地址?

66

在C编程语言中,如何手动分配指针地址(例如将其分配到内存地址0x28ff44)?


7
毋庸置疑,除非在某些嵌入式系统中,否则这是一项相当无意义--甚至可以说是自杀式的--练习。 - user395760
3
你一定喜欢“分段错误”(Segmentation fault)了。 - Indra
@IndrajithIndraprastham 是的,那是很久以前的事了,我对这个东西很好奇。 - Irakli
@Irakli:是的,我知道那是3年前的事了。今天我尝试了一下,结果出现了分段错误。我试图通过另一个程序改变在一个程序中分配的整数的值。 - Indra
5个回答

92

就像这样:

void * p = (void *)0x28ff44;

或者如果你想要一个char *类型:

char * p = (char *)0x28ff44;

如果你指向的是真正不应该改变的东西,就加上const关键字:

const void * p = (const void *)0x28ff44;
const char * p = (const char *)0x28ff44;

我想这肯定是某种“众所周知的地址”,通常(但并不总是)是只读的。


2
请纠正我如果我错了。但是在C语言中,将一个无效地址分配给指针不是未定义的行为吗?与使用指针算术产生指向无效对象、不在数组内或指向1个元素之后的结果一样,这也是不允许的吧? - dhein
3
@Zaibis:我认为编程语言C本身并没有明确表示这一点。重要的是您使用该语言的系统。Delnan在对问题的评论中说得很好:"毫无疑问,除了某些嵌入式系统外,这是一个非常无意义(如果不是很危险)的练习。"硬编码指针值的用例非常少,但确实存在一些。早年间,我记得在DOS中直接访问显示内存...;-)因此出现了上面提到的“众所周知的地址”评论。 - T.J. Crowder
1
@pauluss86:可能有,但我已经20年没有使用C++了,那时候我不认为它们有这些功能... :-) - T.J. Crowder
3
@T.J.Crowder - 实际上,硬编码指针有很多用途。这在微控制器中经常发生,在“正常”系统的引导加载程序和驱动程序中也是如此。通常,指针本身可以是const,但它所指向的数据不是。大多数程序员从未看到过这段代码,也不知道它是如何工作的。虽然我可以补充一下 - 这正是C仍然最相关的地方,因为越来越少的应用软件有任何真正需要用C编写的理由。 - Brian McFarland
1
@geeeeekyDeveloper - 这意味着你正在将“p”设置为指向你不允许写入的内存。 - T.J. Crowder
显示剩余8条评论

11

你的代码应该像这样:

int *p = (int *)0x28ff44;

int需要是您引用的对象的类型,或者可以是void

但要小心不要访问不属于您程序的内容。


5
int *p=(int *)0x1234 = 10; //0x1234 is the memory address and value 10 is assigned in that address


unsigned int *ptr=(unsigned int *)0x903jf = 20;//0x903j is memory address and value 20 is assigned 

基本上在嵌入式平台中,我们使用直接地址而不是名称。

1
写作: int *p=(int *)0x1234 = 10; 对于某些编译器来说是不合法的。你需要分成两个指令: int *p=(int *)0x1234; *p = 10; - Phil
更不用说你不能给程序没有“拥有”的随机内存地址分配值。如果您尝试访问内存地址的值(读取或写入),程序很可能会关闭。操作系统会禁止这样做,以防止恶意程序更改内存,从而导致有害故障。 - Themud
@Themud,你是对的,你可能会因为尝试读取其他程序的内存而得到“分段错误(核心已转储)”。 - Smeterlink

2

假设您想要一个指针指向地址0x28ff4402,通常的方法是

uint32_t *ptr;
ptr = (uint32_t*) 0x28ff4402 //type-casting the address value to uint32_t pointer
*ptr |= (1<<13) | (1<<10); //access the address how ever you want

所以简单的方法是使用宏。
#define ptr *(uint32_t *) (0x28ff4402)

0
在嵌入式系统中分配内存时,必须使用volatile关键字,否则编译器优化可能会忽略更新后的值并使用旧值。以下是一种安全访问内存的方法。
#define ptrVar (*((volatile unsigned long *)0x400073FC)) //ptrVar points to memory location 0x400073FC

ptrVar =10// write 10 at the memory location

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接