' char'的奇怪行为指针

时间:2012-07-28 08:31:20

标签: c

当我声明并运行以下内容时,它会给我一个segmentation fault

main()
{
    char *p = "boa";
    *(p+1) = 'y';
    printf("%s",p);
}

我怀疑char *p是一个常数等等。

但以下工作正常。

main()
{
    int i = 300;
    char *p = (char*)&i;
    *(p+1) = 'y';
    printf("%s",p);
}

这背后的原因是什么?上述规则也不适用于此吗?

3 个答案:

答案 0 :(得分:3)

这取决于你对“工作正常”的定义。但是赋值不是分段错误的原因是因为p指向i变量的地址,这显然不是常数。 i被赋予了一个常量值,但i本身不是常量。

对于i = 300(假设小端x86):

  +--+--+--+--+
i:|2c|01|00|00|
  +--+--+--+--+
  .
 /|\
  |

p:&i

*(p+1) = 'y'之后

  +--+--+--+--+
i:|2c|79|00|00|
  +--+--+--+--+
  .
 /|\
  |

p:&i

因此,print语句恰好为您打印,y,但这只是因为您依赖于平台的字节顺序(2c是一个可打印的ASCII字符)。在大端机器上,和/或它是非ASCII的情况可能会有所不同。

答案 1 :(得分:1)

哦,男孩......

第一个由于字符串为const而导致的seg-faults(你已经做到了这一点)。然而,第二个是对指针语义的迷人滥用! ; - )

以下是您在第二个示例中所做的事情:

  • 拥有一个带有值的随机int号码(在您的情况下为300
  • 获取int的地址 - 基本上是一个地址,该地址包含(32位?)int 300并将其转换为char*,其中每个元素指向8位值
  • 获取“第一个”8位值的地址,递增1(递增8位(!))并将这8位的值更改为数字ASCII码“y”
  • 打印“结果字符串”

答案 2 :(得分:1)

区别在于:

char *p="boa";

p指针。您正在p指向无法修改的字符串文字"boa",当您尝试修改它时会发生段错误。

int i=300;
char *p=(char*)&i;

iint类型的变量,您只需使用常量300来初始化i并执行300值的按位副本进入i的位置,但是从不指向常量本身,只是将其用作初始化程序。这是差异,第一个示例中的p指向常量字符串文字,而在第二个示例中,它指向int类型的变量。因此,稍后使用指针i修改p的位置很好,因为您正在修改非常量对象i