2013-08-24 46 views
1

假設我調用一個函數void foo (char* fileName);通過以下調用使用的strcat()作爲參數傳遞給函數

foo("file.txt"); 

它是確定調用foo()有:

foo(strcat("file.txt",".binary")); 

會造成任何記憶問題?據我瞭解,我可以面對的唯一問題是堆棧溢出,對吧?

+2

你不是真的把兩個字符串拼接在一起,對嗎?你的實際代碼是什麼? –

+0

@TimCooper,沒有實際的代碼,我只是想知道如果我使用'的strcat()',而使用'fopen()函數'例如,將導致堆棧錯誤。 – Quaker

回答

1

它會導致任何內存問題?

是的,這是未定義的行爲,所以可能會導致崩潰。

據我所知,我唯一可以面對的問題是堆棧溢出,對吧?

不,這裏的問題是,strcat將試圖超過字符串文字的末尾寫入。

你可以修改你的程序如下:

// Copy into writable memory, and give enough space to fit ".binary" 
char fileTxt[16] = "file.txt"; 
foo(strcat(fileTxt,".binary")); 

另外,與字符串文字編譯器會爲你做串聯,如果你簡單地把它們一前一後:

foo("file.txt" ".binary"); 
+0

您提到的方法是否可以在任何C編譯器中使用? – Quaker

+0

@Quicker是的,這是標準的一部分,第6.4.5.7節。 – dasblinkenlight

2

的問題是,對於strcat,第一個參數將被用於存儲結果,所以它必須足夠大,以包含串聯的結果字符串。

在你的例子中,第一個參數是一個字符串,它不能被修改,並不是說有足夠的空間。

1

它將碰撞; OSX下,我得到:

$ ./a.out 
Abort trap: 6 

以下堆棧跟蹤:

0 libsystem_kernel.dylib   0x00007fff8ad85866 __pthread_kill + 10 
1 libsystem_pthread.dylib   0x00007fff83cb136c pthread_kill + 92 
2 libsystem_c.dylib    0x00007fff8455dbba abort + 125 
3 libsystem_c.dylib    0x00007fff8455dd31 abort_report_np + 181 
4 libsystem_c.dylib    0x00007fff845818c5 __chk_fail + 48 
5 libsystem_c.dylib    0x00007fff845818d5 __chk_fail_overlap + 16 
6 libsystem_c.dylib    0x00007fff845818f7 __chk_overlap + 34 
7 libsystem_c.dylib    0x00007fff84581c29 __strcat_chk + 81 
8 a.out       0x0000000105c63f09 main + 57 
9 libdyld.dylib     0x00007fff8f2255fd start + 1 

您正試圖在一個字符串常量,它常常會設在只讀存儲器複製。

1

第二個字符串的起始字節覆蓋第一個字符的空字節。所以第一個字符串(除了不是上面提到的字符串字面量之外)應該足夠大以容納兩個字符串的所有字符加上字符串字符的結尾。而且,這些字符串不應該重疊。

相關問題