从手动分配地址的指针访问值

时间:2013-11-08 06:52:19

标签: c pointers

我已经为一个特定数据类型的指针分配了一些随机地址。然后我在该特定地址中存储了一个值。当我运行程序时,它会突然终止。

char *c=2000;
*c='A';
printf("%u",c);
printf("%d",*c);

我可以在第一个c语句中打印printf的值。但我无法通过第二个获取存储在该地址中的值。我已经在Cygwin GCC编译器和在线ideone.com编译器中执行了。在ideone.com编译器中,它显示运行时错误。这背后的原因是什么?

2 个答案:

答案 0 :(得分:2)

当您将地址2000分配给指针c时,您假设这将是一个有效的地址。但一般来说,它不是有效的地址。您不能随意选择地址,并期望编译器(和操作系统)已分配该内存供您使用。特别是,第一页内存(通常为4 KiB,通常至少为1 KiB)完全不受限制;所有读取或写入的尝试通常都指示错误而非故意行为,并且MMU(内存管理单元)配置为拒绝访问该内存的尝试。

如果您使用的是嵌入式微处理器,规则可能会有所不同,但在像Cygwin的Windows这样的通用软件中,0x1000(4 KiB)以下的地址通常是禁止的。

你可以打印地址(你做得不可靠,但可能是你的编译器没有警告你;我会警告我使用4字节整数的格式打印8字节地址)。但是您无法在地址处可靠地读取或写入数据。可能有机器(通常是大型机),只需读取无效地址(即使没有访问它指向的内存)也会产生内存故障。

因此,正如Acmeanswer中所说,你调用了未定义的行为。您已从编译器负责为指针分配有效地址,但您选择了无效值。崩溃是你做出错误决定的结果。

答案 1 :(得分:1)

char *c=2000;

对指针的整数值的赋值(和初始化)是实现定义的行为。

  

实现定义的行为由ISO C标准定义   第3.4.1节:

     

unspeci fi ed行为,其中每个实现都记录了如何选择   是

     

示例实现定义行为的示例是   当有符号整数移位时,高位的传播   右。

     

任何依赖于实现定义行为的代码都是   保证在特定平台和/或编译器下工作。手提   程序应该尽量避免这种行为。

相关问题