[英]bug on RELEASE but not on DEBUG
std::string s("foo");
sprintf(buf,"%s",s);
為什么至少在MSVC 2010下,此行代碼不會在DEBUG中出錯,而在RELEASE中出錯?
%s
格式說明符期望以NULL結尾的char*
。 您正在傳遞一個std::string
實例。 如果它在DEBUG中有效,那就太幸運了。
您應該使用:
std::string s("foo");
sprintf(buf, "%s", s.c_str());
這將提取一個char*
並確保緩沖區以NULL終止。
在運行時庫中, std::string
可能對DEBUG和RELEASE具有不同的實現。 嘗試使用這兩種設置進行編譯,但是將調試符號添加到RELEASE構建中,然后逐步執行代碼。 查看存儲s
的存儲位置。 有什么區別嗎?
像sprintf()
這樣的可變參數函數並不是嚴格類型安全的,因為(在編譯時)任何可變參數類型都可以作為可變參數集的一部分被接受。
如其他答案所示, "%s"
是一種格式說明符,期望以NULL
結尾的字符串。 在這種情況下,傳遞std :: string可能是不確定的。
如果它在DEBUG模式下工作,則很可能是“幸運的”,因為該實現恰好會打印正確的結果(可能源於std :: string對象的c樣式強制轉換為字符指針)。
那不行 很可能是您遇到未定義的行為。
std::string s("foo");
sprintf(buf,"%s",s.c_str());
實際上,您實際上應該使用流。
那是錯的。 您應該這樣寫:
std::string s("foo");
sprintf(buf,"%s",s.c_str());
無法將類型為std::string
的對象傳遞給sprintf
因為沒有格式說明符對應於std::string
。 此外, %s
期望使用char*
或char[]
類型的對象,並且c_str()
函數返回char*
,因此上述方法可以正常工作。
如果要混合使用c和c ++,則(出於性能原因,基於您的評論),將函數包裝在c ++中以避免這些細微的錯誤是個好主意。
struct console_out
{
static void
print(const string& s)
{
sprintf(buf, "%s", s.c_str());
}
//other overloads should you want them
}
請小心一次,然后讓編譯器小心。
有時我認為這樣的錯誤在c和c ++中太容易了,但是我們可以解決。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.