const std::string makeUniqueName()
{
srand(time(NULL));
std::string s;
std::generate_n(const_cast<char*>(s.c_str()), 10, RndGenerator());
return s;
}
此代碼是否安全:編譯器不報告任何警告消息。此代碼是否安全?
const std::string makeUniqueName()
{
srand(time(NULL));
std::string s;
std::generate_n(const_cast<char*>(s.c_str()), 10, RndGenerator());
return s;
}
此代碼是否安全:編譯器不報告任何警告消息。此代碼是否安全?
該代碼顯然通過寫入尚未分配的內存來調用未定義的行爲。要麼爲這些字符構建足夠空間的字符串(std::string s(10, 0);
)並將std::begin(s)
傳遞給generate_n
或使用std::back_inserter
。
此外,通過在const
指針使用const_cast
,你再次調用未定義行爲(從const
物體移除const
,然後寫它是不確定的行爲)。
另請參見:不返回const
值,它禁止移動語義,你做而不是想要的。
這個函數的完整實現看起來像使用你的建議? –
@MagnusHoff,好吧,我認爲OP應該處理用我的建議替代他自己代碼的部分代碼的任務 - 讀'back_inserter'上的例子或調用'std :: begin()'不是火箭科學。 – Griwes
那麼,如果你想寫入字符串,你需要爲字符串分配一些存儲空間。
也許更重要的是,您必須停止在c_str()
上使用const_cast
。您不允許修改c_str()
指向的內存。就目前而言,您的代碼會調用未定義的行爲。
即使您的代碼每次調用時都不一定會生成一個唯一的名稱。您可能會將它稱爲兩次非常接近,並且time(NULL)
爲這兩個呼叫返回相同的內容。或者您可能會發現即使使用不同的種子,您的RNG也會返回相同的值。
不,它不安全!
您的字符串中沒有任何內容,並且您正嘗試向其添加10個項目。你需要像這樣保留字符串中的空格:
std::string s(10,' ');
如果你要開始直接寫入它。
即使字符串中的內存是預分配的,嘗試使用c_str()指針寫入字符串也是非常糟糕的做法! – benjymous
絕對不安全。 C++標準明確禁止修改c_str指向的值。編譯器不會因爲const_cast而抱怨,但它仍然是錯誤的。
不,當然不是。 'generate_n'需要一個地方寫入數據。 – juanchopanza
如果你發現自己使用'const_cast',但你不明白爲什麼,那麼答案几乎肯定是「不!」 – benjymous
不要使用'.c_str()'作爲可寫內存,請使用迭代器。而**永遠不會通過const值**返回。 – Griwes