(原創) 為什麼int *ptr = 345;這樣的寫法有問題? (C/C++) (C)

Abstract
這是一個初學者常犯的錯,不過卻是一個很好的問題,充分表現出指標的特色。

Introduction
一個很簡單的C語言,只有6行。

C語言

1 #include <stdio.h>
2 
3 int main() {
4   int *ptr = 345;
5   printf("%d\n", *ptr);
6 }


在不同的compiler會有不同結果,在VC6不能編譯,會有錯誤訊息,在VC8則無錯誤訊息,但run-time會錯。

4行

int *ptr = 345;


主要問題在這一行,原作者認為ptr是一個指向int的指標,將ptr指向345這個整數,所以認為下一行的*p應該會顯示345。這樣看起來相當合理。

蔡明志Turbo C深入解析p.11最後一段解釋了這種寫法的問題:

理由在於當我們宣告int *ptr的時候,它是屬於自動(auto)儲存類別,指標變數ptr的內容是當時殘存於&ptr這塊記憶體內的垃圾值(garbage value);因而(*ptr = 345;)這條敘述會把345存放在不適當的地方,這個地方可能是其他資料區域,也可能是根本尚未配置的記憶區塊,總而言之,這種做法是既不明智又有危險的。


也就是說,當宣告int *ptr時,只是宣告了在記憶體中,有一塊位址為ptr這個指標變數所占有,但ptr變數目前所存放的位址尚未指定,所以ptr變數目前有幾個可能:
1.有個垃圾值,指向一個安全的地方
2.有個垃圾值,指向一個已經有資料的地方

若運氣好遇到第一種狀況就沒事,若運氣不好,遇到第二種狀況,將345存到一個目前有資料的地方,當然造成當機,所以這種寫法有問題。

正確的寫法應改成
C語言

1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com
3 
4 Filename    : pointer_error01.c
5 Compiler    : Visual C++ 8.0
6 Description : Demo pointer error
7 Release     : 03/27/2008 1.0
8 */
9 #include <stdio.h>
10 
11 int main() {
12   int i = 345;
13   int *p = &i;
14   printf("%d\n", *p);
15 }


執行結果

345


為什麼這樣寫就安全呢?因為

12行

int i = 345;


345已經被放在變數i這個安全的地方。

13行

int *p = &i;


然後再將i的記憶體位址指定給p,如此p就能『安全』地指向345了。

Conclusion
一個只有6行的程式,就能考驗你對指標的概念,C語言就是這樣,只要想通了,就非常有趣。

Reference
蔡明志, 1991, Turbo C深入解析, 松崗

posted on 2008-03-27 22:39  真 OO无双  阅读(8668)  评论(5编辑  收藏  举报

导航