2016-08-14 110 views
-4

我想知道为什么这段代码没有按预期工作。堆栈是否连续增长?

typedef char uint8; 

    int main(int argc, const char * argv[]) { 
    // insert code here... 

    uint8 number_1 = 3; 
    uint8 number_2 = 1; 
    uint8 *PointerToNumber = &number_1; 

    printf("%d \n", *PointerToNumber); 
    ++PointerToNumber; 
    printf("%d \n", *PointerToNumber); 

    return 0; 
} 

该程序打印3和-112。但是,如果堆栈不断增长,它不应该打印3和1吗?

因此,如果我指向number_1,然后增加类型为uint8的指针地址不应该指向number_2,因为它是在number_2之后声明的?

+7

这不是堆栈增长的问题,而是编译器如何选择排列局部变量的问题。 –

+3

两个变量之间可能有未使用的字节......并且不能保证变量被放置在任何特定的位置或顺序中,或者甚至被包括在内(根据它们的使用方式,它们可以被优化)。 – Dmitri

+0

不能依赖于局部变量在内存中的位置,但'number_2'可能位于'number_1'后面的下一个较低地址处。 –

回答

3
++PointerToNumber; 
printf("%d \n", *PointerToNumber); 

导致未定义的行为。试图证明任何行为是毫无意义的。程序的行为可能随着优化级别,不同编译器选项和不同编译器的更改而改变。

在这种情况下,优化程序可以选择不为number_2分配任何空间,因为它没有在函数中使用。

0

好像有人评论过,number-2可能在number_1之后的下一个较低的地址。 因此,而不是在执行++ PointerToNumber,--PointerToNumber创建预期结果(打印“1”)。

+0

再次,没有保证。尝试编译优化,看看它是否仍然有效。另外,通过优化,我可以得到您期望的原始代码的结果,因为我的编译器对变量进行了不同的排序,并且优化后的结果都不起作用。 – Dmitri

+0

是的,我知道这一点。我只想验证堆栈的整体概念作为LIFO内存。 – user148013

+0

局部变量的放置与作为LIFO的堆栈无关。当一个函数被调用时,通常发生的事情是调用者将参数和返回地址压入堆栈并调用该函数。被调用函数然后将帧指针设置为堆栈指针的值。然后,堆栈指针会减少函数为本地存储所需的空间量。局部变量被分配到该空间中的位置(表示为来自帧指针的负偏移),但它们可以在那里的任何位置。这完全取决于编译器。 –