簡體   English   中英

發布時出現錯誤,但調試失敗

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM