3

我不明白这条线是做什么的:

((struct Example*) 0x10000)

我写了一个测试程序:

#include <stdio.h>

struct Elf{
    int bla;
    char bla2;
};

int main(){
    struct Elf *elfPtr;
    printf("Before casting: %p\n", elfPtr);
 
    elfPtr = ((struct Elf *)0x10000);
    printf("After casting: %p\n", elfPtr);
 
    return 0;
}

输出是:

施法前:0xb776dff4

施法后:0x10000

这条线只做这个吗?

elfPtr = 0x10000
4

4 回答 4

5

这确实将指针设置为特定的常量值,这在具有虚拟内存管理的系统中是一个坏主意。

一个值得注意的例外是具有内存映射资源的嵌入式系统。在这样的系统中,硬件设计人员通常会保留一系列内存地址以供替代使用,让程序员可以访问硬件寄存器,就好像它们是常规内存空间的一部分一样。

这是一个示例*

struct UART {
    char data;
    char status;
};
const UART *uart1 = 0xC0000;
const UART *uart2 = 0xC0020;

有了这个设置,嵌入式程序就可以访问 UART 的寄存器,就好像它们是struct的成员一样:

while (uart1->status & 0x02) {
    uart1->data = 0x00;
}


* UART 代表Universal Asynchronous Receiver/Transmitter,一种常用于异步对等通信的硬件。

于 2013-09-29T12:13:17.720 回答
2

通常,将任意值分配给指针是一个坏主意。这就是编译器不鼓励它的原因,您需要添加强制转换以向编译器保证您知道自己在做什么。

(您的代码会将地址 0x10000 处的内存视为一个struct Elf实例,至少在您的简单示例中,它不是。它甚至可能不是可读和/或可写内存,因此当您尝试访问它。)

于 2013-09-29T12:05:14.653 回答
1

该行elfPtr = ((struct Elf *)0x10000);将使 * Elf *类型的指针指向十六进制数 0x10000(十进制为 65536)标识的内存地址

所以无论那个内存地址有什么,你都假设它是“Elf”类型的

于 2013-09-29T12:09:40.050 回答
0

使用该命令,您告诉编译器地址 0x10000 处的数据是“Elf”类型结构的实例,并将该类型的指针分配给该地址。

请注意,您没有在该地址实例化该类型的任何结构,甚至没有为其保留内存,因此在尝试引用其成员时,如果不是分段错误,至少您会得到垃圾。

你真的应该避免使用绝对地址(除非例如低级微控制器编程),它会导致不可移植的代码,如果它甚至运行的话。

于 2013-09-29T12:09:35.913 回答