假設我調用一個函數void foo (char* fileName);
通過以下調用使用的strcat()作爲參數傳遞給函數
foo("file.txt");
它是確定調用foo()
有:
foo(strcat("file.txt",".binary"));
會造成任何記憶問題?據我瞭解,我可以面對的唯一問題是堆棧溢出,對吧?
假設我調用一個函數void foo (char* fileName);
通過以下調用使用的strcat()作爲參數傳遞給函數
foo("file.txt");
它是確定調用foo()
有:
foo(strcat("file.txt",".binary"));
會造成任何記憶問題?據我瞭解,我可以面對的唯一問題是堆棧溢出,對吧?
它會導致任何內存問題?
是的,這是未定義的行爲,所以可能會導致崩潰。
據我所知,我唯一可以面對的問題是堆棧溢出,對吧?
不,這裏的問題是,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");
您提到的方法是否可以在任何C編譯器中使用? – Quaker
@Quicker是的,這是標準的一部分,第6.4.5.7節。 – dasblinkenlight
的問題是,對於strcat
,第一個參數將被用於存儲結果,所以它必須足夠大,以包含串聯的結果字符串。
在你的例子中,第一個參數是一個字符串,它不能被修改,並不是說有足夠的空間。
它將碰撞; 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
您正試圖在一個字符串常量,它常常會設在只讀存儲器複製。
第二個字符串的起始字節覆蓋第一個字符的空字節。所以第一個字符串(除了不是上面提到的字符串字面量之外)應該足夠大以容納兩個字符串的所有字符加上字符串字符的結尾。而且,這些字符串不應該重疊。
你不是真的把兩個字符串拼接在一起,對嗎?你的實際代碼是什麼? –
@TimCooper,沒有實際的代碼,我只是想知道如果我使用'的strcat()',而使用'fopen()函數'例如,將導致堆棧錯誤。 – Quaker