内存中的变量

问题描述:

如果我有两个变量a我b都是int,并且一个指针ptr指向& b。如果我们会像这样增加ptr ++,它应该指向a,如果我没有错的话。我认为这是可能的,因为当编译一个我在堆栈和B有4个字节小于A.但是当我在下一行打印那个指针时,我只能得到地址。 代码:内存中的变量

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int a = 52; 
    int b = 12; 


    int *ptr; 
    ptr = &b; 

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



    return 0; 
} 

但如果我把的printf( “%d”,&一个);那么最后的printf打印好并打印 码的值:

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int a = 52; 
    int b = 12; 

    printf("%d\n",&a); 
    int *ptr; 
    ptr = &b; 

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



    return 0; 
} 

有人能解释我为什么出现这种情况? 图片:

enter image description here

+6

您不能将指向一个对象的指针递增指向另一个对象,除非这两个对象是同一个数组的一部分。您的程序展示未定义的行为。 – EOF

+0

我知道,关于数组,实际上他们正好落后于另外4个字节,并且他们将总是蜜蜂,只有当我使用更多的变量不同的类型,然后之间的空间不会相等。 – honeyPot

+0

您的第一个程序从不使用'a',因此编译器正在优化内存分配和/或分配。第二个程序使用它,所以它得到内存分配。 – Barmar

编译器可以*安排它在堆栈中选择的任何顺序的局部变量。事实上C标准甚至没有提到堆栈。这是编译器的实现细节。

添加看似不相关的代码行可能会导致编译器决定以不同于没有附加代码的顺序将变量放置在堆栈上。所以在编写代码时你不能依赖这种行为。这样做是你经历过的undefined behavior

此外,对不属于同一数组的变量执行指针运算也是未定义的行为。

你不能保证ab变量是近记忆存储在任何地方,这是普通的不安全的指针递增,从一个尝试“旅行”到另一个,和依靠结果。你正在做的事是陷入未定义行为的领域,你不应该那样做。

C11草案标准n1570:

6.5.2.4后缀增量和减量运算

[...]见添加剂运营商对于 讨论和化合物分配关于约束条件,类型和转换的信息以及操作对 指针的影响。[...]

6.5.6加法运算符

对于这些操作符的目的,一个指针到一个对象,它是不是一个 数组的元素的行为相同的指针第一长度为1的数组的元素,该对象的类型为 作为其元素类型。

[...]如果两个指针 操作数和结果指向相同的数组对象的元素,或一个过去的阵列对象的最后 元件,评价不得产生溢出;否则, 行为未定义。如果结果指向一个超过数组对象的最后一个元素,则不应将其作为被评估的一元运算符的操作数使用 。

ptr = &b;ptr++;后,printf("\n%d",*ptr);提领ptr不确定的行为