2017-08-03 64 views
1

我发现在嵌入代码负索引访问我调试:我可以保证使用负移位访问指针吗?

for (int i = len; i > 0; i--) 
{ 
    data[i - 1] = data[i - 2]; // negative access when i == 1 
} 

我读this关于类似的情况,但在OP arr[-2]保证是因为arr点的先前中间OK分配数组。就我而言,data是一个类中的指针由构造与初始化:

public: 
    constructor_name(): ... data(new T_a[size]), ... 

和指针data在类中的第一个成员:

template <class T_a, class T_b, int size> 
class T_c 
{ 
private: 
    T_a   *data; 
    T_b   *...; 
    int    ...; 
    int    ...; 
    int    ...; 

public: 
    constructor_name(): ... data(new T_a[size]), ... 

现在,有一个否定索引访问是故意的并且有意义的可能性?有没有一种方法编写程序员能够确保data[-1]将访问特定数据,使用#pragma pack()或其他任何方法?

看到*data是班上第一个让我觉得这是一个bug的成员,但我不确定。如果确实是一个错误 - 是UB

+4

确实是[未定义的行为](https:// en。wikipedia.org/wiki/Undefined_behavior)所以你没有任何保证 –

+0

@BasileStarynkevitch如果'data'位于课堂上其他地方 - 它会有什么区别吗? – CIsForCookies

+0

我不这么认为。关于UB的C++标准非常强大。 –

回答

4

您在询问担保(一个很强的词)。而你的代码有undefined behavior(因为你正在访问你的对象之外的一些数据),这意味着你不能有任何保证。任意坏事could发生,即使在实践中他们通常不会(特别是当data指向一个标量类型,如指针)。

我建议用for (int i = len; i > 1; i--)代替for (int i = len; i > 0; i--)至少使代码更具可读性和更符合标准。

如果出于某种奇怪的原因data[-1]访问权限对以前的程序员有意义,他应该至少已经评论过。我猜如果他不这样做,那简直是一个错误。

1

这取决于您正在使用的嵌入式芯片。

首先,要注意的重要部分是生活在堆中的data。所以通常情况下(在台式电脑中),你不能假定这个data就在你控制的另一条信息的旁边。

但是,正如我们在这里所谈论的嵌入式系统一样,它们中的一些具有用于堆栈和堆的单个连续内存空间,并且开始从该内存空间的一侧填充堆,并从另一侧开始填充堆,直到它们在中心见面,程序崩溃。

不管怎样,在这种情况下,你的代码的程序员会如此谨慎,他知道这是下一个heap分配会发生,从而保证该变量人住data,但实际上我觉得这是不太可能。尽管如此,他会利用undefined behaviour,因为它是一个"memory access outside of array bounds",我认为这不仅是一个糟糕的编程习惯,而且是一个错误。

找到了堆堆栈模型如何在特定芯片here中工作的图片。

+0

它仍然是[未定义的行为](https://en.wikipedia.org/wiki/Undefined_behavior) –

+0

同意,这是未定义的行为。 – MondKin

+0

所以我会在你的回答中提到UB。 OP询问“保证” –