3
void Test2()
{   
    int c=8;
    int b=7;
    int d=9;
    int *a; 

    a = &b;
    a+=sizeof(int); //I supposed that *a should points on variable d after this 

    cout << "b\t" << &b << "\t" << b << endl;
    cout << "a\t" << a  << "\t" << *a << endl;
    cout << "c\t" << &c  << "\t" << c << endl;
    cout << "d\t" << &d  << "\t" << d << endl;
}

我认为*a应该指向变量d,因为bd(如我所想)位于局部变量堆栈附近。但是 *a 指向另一个地址,所以*a != d 我的问题是为什么会这样?它是 Visual Studio 2010 的功能还是其他什么?

4

4 回答 4

9

不,这是 C++ 的一个特性,称为未定义行为。您不能在您拥有的数组(或数组边界上的一个位置)之外进行指针算术。

你可以让它工作,a += 1因为a它已经是 a int*,所以+= 1让它指向下一个整数。a+=sizeof(int)将其sizeof(int)向右移动整数。

 +------+------+------+------+------+
 |      |      |      |      |      |      
 +------+------+------+------+------+
    ^      ^                    ^
    |      |                    |
    a     a+1               a+sizeof(int) (assuming sizeof(int) == 4)

同样,从技术上讲,它是未定义的。

于 2012-09-13T07:28:55.507 回答
7

好吧,对于初学者来说,我认为指针算术不像你认为的那样工作。您不需要这样做sizeof(int),因为指针已经是指向 的指针int,所以编译器知道a++需要提前 4 个字节。

其次,不,您不能指向局部变量,因为您不知道编译器将它们放在内存中的什么位置、它们的生命周期,甚至根本不知道它们是否在内存中。编译器会将许多局部变量优化到 CPU 寄存器中。

编辑:是的,根据有效的评论,我应该澄清你可以使用指向局部变量的指针,编译器会做正确的事情,但你不能对它们使用指针算术,因为它们可能会被完全优化掉。

于 2012-09-13T07:31:43.793 回答
3

您不能假设所有变量都按照您想要的方式对齐,并且您不能以这种方式使用指针算术。安全使用它的唯一方法是在您的数组范围内使用它。此外,a+=sizeof(int)不会将其移动到指向下一个整数,而是将其移动sizeof(int)整数。

您在这里依赖 UB,因此您不能期望任何特定的结果。实际上,您甚至可能会遇到段错误。

于 2012-09-13T07:28:51.527 回答
0

不,它不是 Visual Studio 2010 的功能。指针的算术运算显示未定义的行为。

通常,仅在指向数组元素时使用增量/减量

于 2012-09-13T07:31:22.200 回答