2017-02-10 50 views
2

從C11標準(草案):7.21.6.2/12使用的scanf%P UB

如果輸入項是同一程序 執行,該結果應比較等於指針時較早轉換的值價值; 否則%p轉換的行爲是未定義的。

有人可以提供這部分標準的代碼請。無法理解從輸入中獲取%p的用法。

+3

如果你有一個指針變量'p',printf使用'%p'轉換,然後在同一個進程中使用相同的'%p'轉換複製,粘貼和scanf到另一個指針變量'q'中,然後'p == q'。 – DyZ

+0

你不想像''printf''那樣將8088的分段指針值(比如'5:abcd')取出並掃描到386的扁平體系結構中。 – alk

+1

請注意,指針 - >文本 - >指針的成功往返將導致「比較等於該值」的指針。原始指針和最終指針可能仍然有不同的位編碼,但相當於_values_,就像'+0.0 == -0.0'一樣細節取決於平臺。 – chux

回答

5

首先,下面是使用的輸入和輸出的串版本中的一個小的演示(demo):

int val = 123; 
char buf[100]; 
sprintf(buf, "%p", (void*)&val); 
printf("Original =%s\n", buf); 
void *ptr; 
sscanf(buf, "%p", &ptr); 
printf("Read back=%p\n", ptr); 
int *iPtr = ptr; 
if (iPtr == &val) { 
    printf("Pointers match\n"); 
} 

sprintf在頂部寫指針到輸出緩衝器; sscanf將其讀回。

送入sscanf比賽正是由sprintf生成的字符串,所以標準保證iPtr == &val是要評價對true,和行爲的字符串被定義。傳遞一個不匹配由同一個正在運行的程序生成的任何內容的字符串將是未定義的行爲。

+1

你確定'int * ptr;'和'...(void **)&ptr);'確定嗎?我認爲'void *'和'int *'不必是相同的大小。我期望'void * p; ... sscanf(buf,「%p」,&p);' – chux

+2

@chux這是一個很好的觀點,非常感謝你!你說得對,''printf'足夠好,但對scanf'不夠好。 – dasblinkenlight

+0

@chux再次感謝!這不是一個例子,它是一個「太多C++」的例子 – dasblinkenlight

0
int main(){ 
    int c =5; 
    int *p; 
    printf("Address of C: %p\n Please Enter the above address: " , &c); 
    scanf("%p", &p); 
    *p=10; 
    printf("\nNew value of C: %d", c); 
} 

您可以通過scanf手動設置指針。但是,如果你有一個錯字,會很危險。

+1

關閉,但打印和掃描的指針類型不太正確。 – chux