2013-05-21 53 views
2

在我的程序中,我使用basename函數來獲取分區。 第一,我寫了,如果喜歡這句話:這兩個代碼塊有什麼區別?

if (!strncmp(buf, 
    basename("/dev/mmcblk0p3"), 
    strlen(basename("/dev/mmcblk0p3"))) { 
    ret = 1; 
} else { 
    ret = 0; 
} 

BUF點串 「mmcblk0p3」,但RET = 0,用gdb,我發現基本名稱( 「的/ dev/mmcblk0p3」)返回一個怪異的串,但是當我改變這樣的程序:

char *p = NULL; 
p = basename("/dev/mmcblk0p3"); 
if (!strncmp(buf, p, strlen(p)) { 
    ret = 1; 
} else { 
    ret = 0; 
} 

ret是1,程序運行正常。有什麼不同? basename不能像這樣使用?編譯環境是armel7v/gcc。

+0

什麼是'buf'?那裏有什麼? –

回答

1

使用返回字符串的非可重入函數基本名稱的一個後果是您的後續調用使先前的結果無效。您需要在進行第二次呼叫之前複製返回值,或者在第二次呼叫返回後停止使用舊值。這是因爲basename只有一個內部緩衝區來存儲它的結果,假設它沒有修改它的參數(這看起來就是你的程序的情況,因爲它不會在字符串文本上崩潰;但它仍然是未定義的行爲)。

修改你的程序如下,使其便攜:

char *p = NULL; 
char pathname[] = "/dev/mmcblk0p3"; 
p = basename(pathname); 
if (!strncmp(buf, p, strlen(p)) { 
    ret = 1; 
} else { 
    ret = 0; 
} 
3

古典(POSIX)basename()函數可能會修改其輸入字符串。

看起來你的版本修改輸入,所以第二個調用沒有得到相同的字符串作爲第一個,使上述代碼非常混亂。

更糟糕的是:您還調用了未定義的行爲,因爲basename()修改了字符串文字。