簡體   English   中英

C變量不在我期望在內存中找到的位置

[英]C variable not where I expect to find it in memory

有人可以解釋為什么打印指向兩個int的指針會導致它們相對於char放置在不同的位置。

下面的代碼應該從&a到&c打印出內存地址,(我認為)應該包括定義的兩個int,但是不包括,但是當我嘗試找出它們在內存中的存儲位置時(請參閱第二代碼)段),並按預期在兩個字符之間打印它們。

請解釋為什么打印int指針會影響存儲在內存中char之間的int。

這兩個代碼示例是相同的,除了代碼2具有額外的行printf("\\n\\n%p,%p\\n",&i,&j); 打印兩個整數的指針。

編輯:是的,我知道prinf的格式很丑陋,但是代碼只是為了幫助我闡明內存和指針的工作方式,因此我並不需要它很漂亮

代碼1

#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv){
    char a='a';
    int i=1;
    int j=2;
    char c='c';
    char *pos;
    for ( pos=&c; pos<=&a; pos++ ){
        printf("%p\t",pos);
    }
    printf("\n");
    for ( pos=&c; pos<=&a; pos++ ){
        printf("%i\t\t",*pos);
    }
}

Code1的結果

0x7ffde6321e7e  0x7ffde6321e7f  
99              97      

代碼2

#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv){
    char a='a';
    int i=1;
    int j=2;
    char c='c';
    char *pos;
    for ( pos=&c; pos<=&a; pos++ ){
        printf("%p\t",pos);
    }
    printf("\n");
    for ( pos=&c; pos<=&a; pos++ ){
        printf("%i\t\t",*pos);
    }
    printf("\n\n%p,%p\n",&i,&j);
}

Code2的結果

0x7ffc3575616b  0x7ffc3575616c  0x7ffc3575616d  0x7ffc3575616e  0x7ffc3575616f  0x7ffc35756170  0x7ffc35756171  0x7ffc35756172  0x7ffc35756173  0x7ffc35756174  0x7ffc35756175  0x7ffc35756176  0x7ffc35756177  
99              2               0               0               0               1               0               0               0               -4              127             0               97              

0x7ffc35756170,0x7ffc3575616c

您所依賴的注釋1在C標准中未指定。 該行為無法定義。 它調用未定義的行為 筆記2

就是說,您應該始終將%p的參數%pvoid * ,因為期望的類型為void *並且指針沒有默認的提升。


注1:

C沒有提到或保證程序中變量/對象的分配順序。 無法保證它們將具有連續的存儲位置,即增加或減少。 純粹允許它們具有隨機的內存位置,因此您相信的理論是,

 for ( pos=&c; pos<=&a; pos++ )

不成立。 一個實現可以選擇放置( 重新排序 )變量,但確實合適。 關於代碼中它們的定義,絕對不能保證內存地址的順序。


筆記2:

對於關系運算符,請引用C11 第6.5.8章,( 重點是我的

比較兩個指針時,結果取決於所指向對象的地址空間中的相對位置。 如果兩個指向對象類型的指針都指向同一對象,或者都指向同一數組對象的最后一個元素,則它們的比較相等。 如果所指向的對象是同一聚合對象的成員,則指向稍后聲明的結構成員的指針大於指向早於結構中聲明的成員的指針,指向具有較大下標值的數組元素的指針大於指向同一數組的元素的指針下標值較低。 指向同一聯合對象的成員的所有指針比較相等。 如果表達式P指向數組對象的元素,而表達式Q指向同一數組對象的最后一個元素,則指針表達式Q+1比較大於P 在所有其他情況下,行為是不確定的。

因此,對於您的情況,比較pos<=&a; 試圖比較兩個都沒有的指針

  • 指向同一個對象
  • 同一聚合對象的成員
  • 指向數組元素的指針
  • 指向同一聯合對象的成員的指針

簡而言之,它們不在定義的范圍之內,因此,將它們用作關系運算符的操作數會調用未定義的行為。

局部變量的位置由實現定義。 編譯器可以按其認為最佳的順序放置它們。

進行看似無關的代碼更改(例如,額外的打印語句)或更改優化級別,可能會更改編譯器對變量進行布局的方式。

簡而言之,您不能依賴於內存中任何特定的變量布局。

局部變量放置在堆棧中(如果可能,並且未引用其地址,則放置在寄存器中)。 在您的示例中,i是第一個,j是第二個本地變量,因此您有push i, push j -第二個&j的地址是&i-1

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM