2011-12-14 60 views
1

我有一個功能,例如:在C函數的奇怪行爲,字符串不結轉

int foo(void *val){ 
(char *)val="Long String"; 
return 0; 
} 

這個函數被調用,如:

char str[25]; 
foo(str); 
printf("%s",str); 

我什麼也沒有打印出來的某些原因。這裏有什麼問題?

+0

不同的筆記:在這裏使用void指針並不是很好的做法。你不能確定,是否有足夠的空間爲char數組(字符串)保留。我建議檢查一下。 – robustus 2011-12-14 23:10:40

+0

@robustus我的函數實際上不僅僅是foo(* void),還有其他一些參數。 – mugetsu 2011-12-14 23:16:40

回答

2

您指針"Long String"存入其在棧上分配變量val。變量的使用期限僅在致電foo()期間延長。

您不希望將地址存儲在"Long String"的堆棧上。你想拷貝字符串在提供的地址下。

你應該這樣做,而不是:

int foo(void *val){ 
    strcpy((char*)val, "Long String"); 
    return 0; 
} 

這是不安全的,雖然。您應該將緩衝區的最大大小傳遞到foo,並使用strncpy()而不是strcpy()

3

你實際上並不像你認爲的那樣複製數據。您所做的只是將參數值更改爲指向不同的內存地址。該參數是按值傳遞的,因此對其的任何更改都不會反映在調用代碼中。對於您正在嘗試什麼,你需要使用strcpy()strncpy()代替,例如:

int foo(char *val) 
{ 
    strcpy(val, "Long String"); 
    return 0; 
} 

或者:

int foo(char *val, int maxlen) 
{ 
    strncpy(val, "Long String", maxlen); 
    return 0; 
} 
0

您沒有將任何內容複製到str。您只是編輯了您傳入的指針值...

調用foo(str)將創建一個名爲void* val的新臨時變量,並將其指向char[0]。然後,您將val更改爲指向字符串「Long String」的起始位置。

如果你真的想填補char str[25]緩衝,使用strncpy()函數:

int foo (char* buf) 
    { return strncpy (buf, "Long String", 25); } 

但是,如果你曾經發送該例程char[]在它不到25個位置,你有重大問題。

我想也建議,針對一些建議,剛一出現,即strcpy不應該被視爲在新的代碼中使用,並絕對不提倡以人誰是學習如何與指針和文字工作陣列。這就是痛苦。