【发布时间】:2020-10-03 23:43:39
【问题描述】:
int * ptr = (int *) 0x108; // 264 in bin
printf("%d\n", ptr);
我真的不明白发生了什么-当我像++ 这样的操作时,它的值会增加 4(可能是因为 sizeof(int) 是 4)但是有人可以在这里向我解释这是怎么回事吗?访问此类指针时出现错误。为什么?
【问题讨论】:
int * ptr = (int *) 0x108; // 264 in bin
printf("%d\n", ptr);
我真的不明白发生了什么-当我像++ 这样的操作时,它的值会增加 4(可能是因为 sizeof(int) 是 4)但是有人可以在这里向我解释这是怎么回事吗?访问此类指针时出现错误。为什么?
【问题讨论】:
是的,这是一个内存地址,但没有分配给你。如果你在 valgrind 上运行它:
int * ptr = (int *) 0x108; // 264 in bin
printf("%d\n", *ptr);
你明白了
==755107== 地址 0x108 没有被堆栈、malloc 或(最近)释放
您的进程无权访问内存地址。之所以打印264是因为这是0x108的十进制对话
printf( "%d", 0x108);
您向 printf 提供了 %d,printf 尝试将值转换为整数。传%p取回地址
【讨论】:
使用int * ptr = (int *) 0x108;,您的指针指向地址0x108。
如果要设置整数,请使用
int *ptr = malloc(sizeof(int));
*ptr = 0x108
使用printf("%d\n", ptr);,您只需打印 ptr 的内容,假设它是一个数字。这就是您实际打印地址的原因。要打印内容,请使用
printf("%d\n", *ptr);
请注意,当您访问不太可能分配给当前进程的内存时,这(使用您的旧声明和 ptr 设置)应该会出现段错误。
【讨论】:
基本上,是的,您可以将它用于诸如内存映射 I/O 之类的事情。
例如,假设您在嵌入式系统中有一个内存映射随机发生器设备,它将拦截对位置0xf100 的内存访问,并在数据总线上放置一个随机值。您可以使用如下代码:
int getRandom(void) {
static int *randIo = (int*)0xf100;
return *randIo;
}
重要的一点是间接*randIo。从内存位置获取一个值(不是内存位置本身,如果没有间接,它将是randIo)。
在你的情况下是*ptr,而不是ptr。但是在任意(受内存保护的)系统上会做什么将是任何人的猜测:-)
【讨论】:
当我进行像 ++ 这样的数学运算时,它会将值加 4 (可能是因为 sizeof(int) 是 4)但有人可以向我解释 这是怎么回事?
ptr 是指向 int 的指针。当您将整数添加到指针时,您将执行指针算术。 ++ 运算符将指针前进到内存中的下一个 int。如果您机器上的 int 大小为 4 个字节,则地址将以 4 个字节递增。指针算术接近于数组操作。 arr[x] = arr + x。也就是说,如果你想获得数组的第五个元素,你可以使用索引(arr[4])或者你可以使用指针算法(比如 arr + 4)。
请注意,当您访问不太可能分配给当前进程的内存时,这(使用您的旧声明和 ptr 设置)应该会出现段错误。
由于未检查 C 中的数组索引(这是程序员的责任),您可以轻松访问未分配给您的进程的内存地址,这将导致操作系统错误。 对于地址 0x108,您可能总是会出错,因为在某些操作系统中,低地址没有分配给用户。通常是 64K。这样做是为了用指针捕获错误。
【讨论】: