代码之家  ›  专栏  ›  技术社区  ›  mpen

在数组末尾读取是否安全?

  •  3
  • mpen  · 技术社区  · 16 年前

    假设我有这样一个构造器:

    MyColor(uint8 vec[]) {
    r = vec[0];
    g = vec[1];
    b = vec[2];
    a = vec[3];
    }
    

    但我这样称呼它(3个元素而不是4个元素):

    uint8 tmp[] = {1,2,3};
    MyColor c(tmp);
    

    但是现在 vec[3] 未定义…把这个值赋给 a ?如果没有,就没有好的解决办法来检查 VEC〔3〕 有布景吗?

    8 回复  |  直到 16 年前
        1
  •  3
  •   newbie    16 年前

    如果你不想用矢量,试试这个…

    MyColor(uint8 (&vec)[3])
    {
       r = vec[0];
       g = vec[1];
       b = vec[2];
    }
    
    MyColor(uint8 (&vec)[4])
    {
       //...
    }
    
    uint8 a1[] = {1,2,3};
    MyColor c1(a1);
    uint8 a2[] = {1,2,3,4};
    MyColor c2(a2);
    uint8 a3[] = {1,2,3,4,5};
    MyColor c3(a3); // error
    

    您不必显式包含数组的大小,如果尝试传递元素数量错误的数组,将生成编译错误,

        2
  •  19
  •   Mehrdad Afshari    16 年前

    不,这不安全。这是标准定义的未定义行为。它可能会炸毁整个应用程序或返回一个随机值。解决方法是将大小与它一起传递,或使用 vector 相反。

        3
  •  13
  •   sth    16 年前

    不,这不安全。您正在读取尚未分配的内存,这是未定义的行为。根据月球的相位,你可能会或可能不会得到一个分割错误。

    要“解决”它,请确保传入的数组始终具有正确的大小。在您的示例中,您可以执行以下操作:

    uint8 tmp[4] = {1,2,3};
    MyColor c(tmp);
    

    初始值设定项不需要指定所创建数组的所有元素,因此只需显式初始化前三个值即可。其余值将设置为零。

        4
  •  4
  •   Roman PláÅ¡il    16 年前

    不,这不安全。也许您希望将坐标作为参数传递给构造函数并使用两个重载:

    MyColor(uint8 a, uint8 b, uint8 c, uint8 d) {
        stuff
    }
    
    MyColor(uint8 a, uint8 b, uint8 c) {
        stuff
    }
    

    这样你就可以同时使用

    MyColor a(1, 2, 3);
    MyColor b(1, 2, 3, 4);
    
        5
  •  2
  •   David Rodríguez - dribeas    16 年前

    在C++中,与C一样,函数参数数组也会变为指针。现在,根据函数的语义,您可以使用其他方法:

    // explicit parameters (with or without default values):
    mycolor( uint8_t r, uint8_t g, uint8_t b, uint8_t alpha = 255 );
    
    // vector (can check length)
    mycolor( std::vector<uint8_t> const & components );
    
    // array by reference
    mycolor( uint8_t (&components)[ 4 ] );
    

    第一个接近我的方法是最干净的。

        6
  •  1
  •   Billy ONeal IS4    16 年前

    不。这可能会导致一个SegFault。

    比利3

        7
  •  1
  •   vehomzzz    16 年前

    显示的行为未定义,可能会在路上撞车。

    我建议使用vector-along,并使用vector::at()调用访问元素。如果超出了分配的界限,将引发异常。确保在矢量中保留足够的空间

        8
  •  0
  •   Secko    16 年前

    就像你在问在湖上建房子是否安全。总有一天你会在水里醒来。

    在这种情况下,您可能会发现悬空指针会导致系统不稳定和频繁崩溃。

    如果你知道什么是悬空的指针,那么现在的风险是什么。