snprintf比sprintf更安全(注意,snprintf在 Windows和Linux中有區別)

轉自:https://blog.csdn.net/stpeace/article/details/23561425

再轉一篇關於,對snprintf,sprintf在不同平臺上的差別的文章在這裏,從實際操作中,理解帶n與不帶n的函數的差別,觸類旁通啊,strcpy和strncpy,等也是同樣原理

 

So,我們通過代碼來加深一下sprintf和snprintf的差別.  實際上, 在VC++6.0中,用的是_snprintf, 爲了方便起見,敘述的時候,我還是用snprintf.

       看下面測程序(設data爲某一情況下產生的數據):

#include <iostream>
#include <cstring>
#define snprintf _snprintf
using namespace std;
 
int main()
{
    char str[10] = {0};
    char *data = "ab";
    sprintf(str, "debug : %s", data);
 
    cout << str << endl;
    return 0;
}
      我運行上述程序, 非常僥倖, 沒有錯誤。 但是, 我說了,data是某種情況下產生的數據,所以長度有可能不一定,要是萬一data在極端情況下比較長,那會怎麼樣呢?直接上代碼:

#include <iostream>
#include <cstring>
#define snprintf _snprintf
using namespace std;
 
int main()
{
    char str[10] = {0};
    char *data = "abcdefg";
    sprintf(str, "debug : %s", data);
 
    cout << str << endl;
    return 0;
}
      我運行了一下程序,發現程序可以編譯過,但是在運行期間崩潰。要是在大系統中,用戶肯定會找你麻煩,你的產品何談競爭力?


      可以做如下修改:

#include <iostream>
#include <cstring>
#define snprintf _snprintf
using namespace std;
 
int main()
{
    char str[10] = {0};
    char *data = "abcdefg";
    snprintf(str, sizeof(str) - 1, "debug : %s", data);
 
    cout << str << endl;
    return 0;
}
     這樣就安全了,和strncpy非常類似。


     另外,需要特別注意的是: Windows和Linux中的snprintf函數有區別, 在linux代碼中,經常見到snprintf(str, sizeof(str), "...")這樣的用法, 爲什麼這裏不是sizof(str) - 1呢?

我們看看Windows下這麼用會怎樣:

#include <iostream>
#include <cstring>
#define snprintf _snprintf
using namespace std;
 
int main()
{
    char str[10] = {0};
    char *data = "abcdefgddddddddddddddddddddd";
    snprintf(str, sizeof(str), "debug : %s", data);
 
    cout << str << endl;
    return 0;
}
     我運行的時候,程序沒有崩潰,算是萬幸。 但結果亂碼。看來,沒有自動在str最後加'\0',  在linux中, 就安全了, 會自動補哈, 所以永遠不會越界。

     總結一下: 

     1. Linux中, 對於snprintf, 用sizeof(str),  最後會自動加'\0', 比strncpy更安全省事。

     2. Windows中, 就把snprintf和strncpy理解爲類似的, 要用sizeof(str) - 1, 需要注意最後的'\0', 當然啦,你可以在每次用strncpy之前,利用memset將串清零, 這樣比較好。VC++6.0中的_snprintf(snprintf)並沒有按要求實現, 暈。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章