下面一段程式中:
#include <stdio.h>#include <fcntl.h>#include <utmp.h>#include <unistd.h>#include <time.h>int main(){ struct utmp ut; int fd = open(UTMP_FILE, O_RDONLY); int read_len = sizeof(ut); while (read_len == read(fd, &ut, sizeof(ut))) { if ( ut.ut_type != USER_PROCESS ) continue; printf("%-10.10s%-10.10s", ut.ut_user, ut.ut_line); time_t timeTmp = ut.ut_time; int32_t timeTmp1 = ut.ut_time; char *cp = ctime(&timeTmp); printf("%s\n", cp); } close(fd);} 如果你將 char *cp = ctime(&timeTmp) 換做 char *cp = ctime(&timeTmp1),那麼你將會得到錯誤的結果。
我們知道,time_t 是 long int,我64位機上是8Byte的長度,而 int32_t 是4Byte的長度,&相當於是把 timeTmp 的記憶體位址傳遞給 ctime(const time_t *) ,可是當換做 timeTmp1 後,相當於是把記憶體中暫存4Byte長度的 timeTmp1 的記憶體位址傳遞給 ctime() 函數,C函數對於指標的強制轉換編譯可以通過,可是當該函數中使用超出原有資料長度(4Byte)的時候,就危險了,因為其餘資料是不確定的。所以C語言中當我們傳參是指標時,最好確保類型是一樣的,起碼最好確保長度是一致的。
但是,如果是值傳遞,這種情況就不會存在,因為函數內定義的變數是局部變數,調用該函數時分配記憶體單元,存放在棧上,值傳遞相當於是複製,即使是不同類型,使用的當然是複製來的資料,斷然不會出現溢出訪問。即如果把該函數改為:
char *ctime(time_t tmp);
再調用 char *cp = ctime(timeTmp1) 斷然不會出錯。