为什么不提出异常?如果枚举大小小于100字节

时间:2011-11-08 07:00:29

标签: c unions

联合的大小是95个字节,为什么如果我尝试在a处访问102位置,不会引发异常?或者我只是覆盖了另一个内存位置?

   #include<stdio.h>

  union u{
      char a[95];
      int b;
      char *c;
    };

   union u u1;
   int main()
   {
       u1.a[102] = 'b';
       printf("%c",u1.a[102]);
      return 0;
    }

5 个答案:

答案 0 :(得分:5)

这是未定义的行为。你运气不好,什么也没发生。

答案 1 :(得分:4)

您只是在写一个超出范围的内存位置。 C不关心,但你应该。此外,C没有例外(至少不是你在问题中所说的那种例外)。

答案 2 :(得分:2)

是的,你正在覆盖另一个内存位置。没有什么可能立即发生,但如果在真实程序中完成,您可能会覆盖重要数据,并且程序可能会因此而随时崩溃。不可能说出崩溃将会发生什么,或者发生在何时何地发生。

答案 3 :(得分:1)

当你声明一个联合时,你只是说可以用不同的方式读取x个字节。

union u{
      char a[95];
      int b;
      char *c;
    };

这告诉编译器可以将x个字节读取为char数组,整数和char指针。 (另请注意,根据编译器开关,联合可能会用字节填充到偶数个字节)。

union u u1;

当您声明类型为union的变量u1时,您将其声明为全局.data段的成员(请在此处加注)。

现在如果你在联盟说出一个数组之后你会声明一些东西:

char s1[100]; 

它通常会放在.data段中的u1之后。

因为当您尝试在union实例外部写入(95字节)时,u1的大小为95,所以您可能正在写入s1数组。

+----+ <- 0
| u1 |
+----+ <- 94
| s1 | <- u1.a[102];
+----+

C允许你为了效率而做这些事情,它不对阵列进行范围检查,在某些情况下它是一种祝福 - 它允许很多自由 - 但更多时候它会带来麻烦。在您的情况下,您正在访问内存中可能会或可能不会写保护的某个位置。

答案 4 :(得分:0)

C中没有例外。