如果为char分配的值太大而无法放入字节,会发生什么?

时间:2014-02-10 02:10:05

标签: c char integer-overflow

假设我有一个字符指针:

    char * cp;
    int val2 = 2;
    cp = &val2;
    *cp = 1234;

由于值1234太大而无法容纳1个字节会发生什么?它会溢出并导致存储不正确的值,还是会以某种方式将正确的值存储在几个字节中?

1 个答案:

答案 0 :(得分:9)

*cp = 1234;中,*cp仅指一个字节,即val2的第一个(寻址最低的)字节。

在赋值中,右侧的值将转换为左侧的类型。因此,1234将转换为char

这里有两个复杂情况。其中一个,在大多数C实现中,1234太大而不适合char。 (C标准允许char大于8位,但这在现代计算机中很少见。)两个char可以是有符号或无符号的。

如果char是无符号的,那么转换定义得很好:1234比char的最大值(通常为255,因此减少模256)减少一个模数。在通常情况下,1234将减少到210,并且将存储在*cp引用的字节中。

如果char已签名且1234不适合char,则转换是实现定义的,或者引发实现定义的信号。在许多现代C实现中,转换的结果将是-46。

cp之后指向cp = &val2;的字节是val2中寻址最低的字节。它不一定是val2中最不重要的字节。一些C实现存储内存中最低有效字节最低的整数( little endian ),有些C实现存储内存中最高有效字节最低的整数( big endian ) 。 (甚至有些系统不按顺序存储字节;它们可能在内存中混淆。)

大多数现代C实现以二进制形式存储整数而没有填充,因此,一旦你知道C实现是big-endian还是little-endian,你就会知道改变一个字节会如何影响{{1 }}。但是,C标准仍然允许符号或数字补码。它还允许有符号整数中的填充位。

最后,请注意int是一种特殊类型,它允许以这种方式访问​​其他对象的部分。例如,如果您使用char而不是short,就像在char中一样,那将违反别名规则,并且行为将是未定义的。