2014-01-22 198 views
0
const std::string makeUniqueName() 
{ 
    srand(time(NULL)); 
    std::string s;                            
    std::generate_n(const_cast<char*>(s.c_str()), 10, RndGenerator()); 
    return s; 
} 

此代碼是否安全:編譯器不報告任何警告消息。此代碼是否安全?

+3

不,當然不是。 'generate_n'需要一個地方寫入數據。 – juanchopanza

+7

如果你發現自己使用'const_cast',但你不明白爲什麼,那麼答案几乎肯定是「不!」 – benjymous

+1

不要使用'.c_str()'作爲可寫內存,請使用迭代器。而**永遠不會通過const值**返回。 – Griwes

回答

3

該代碼顯然通過寫入尚未分配的內存來調用未定義的行爲。要麼爲這些字符構建足夠空間的字符串(std::string s(10, 0);)並將std::begin(s)傳遞給generate_n或使用std::back_inserter

此外,通過在const指針使用const_cast,你再次調用未定義行爲(從const物體移除const,然後寫它是不確定的行爲)。

另請參見:不返回const值,它禁止移動語義,你做而不是想要的。

+0

這個函數的完整實現看起來像使用你的建議? –

+0

@MagnusHoff,好吧,我認爲OP應該處理用我的建議替代他自己代碼的部分代碼的任務 - 讀'back_inserter'上的例子或調用'std :: begin()'不是火箭科學。 – Griwes

2

那麼,如果你想寫入字符串,你需要爲字符串分配一些存儲空間。

也許更重要的是,您必須停止在c_str()上使用const_cast。您不允許修改c_str()指向的內存。就目前而言,您的代碼會調用未定義的行爲。

即使您的代碼每次調用時都不一定會生成一個唯一的名稱。您可能會將它稱爲兩次非常接近,並且time(NULL)爲這兩個呼叫返回相同的內容。或者您可能會發現即使使用不同的種子,您的RNG也會返回相同的值。

2

不,它不安全!

您的字符串中沒有任何內容,並且您正嘗試向其添加10個項目。你需要像這樣保留字符串中的空格:

std::string s(10,' '); 

如果你要開始直接寫入它。

+0

即使字符串中的內存是預分配的,嘗試使用c_str()指針寫入字符串也是非常糟糕的做法! – benjymous

2

絕對不安全。 C++標準明確禁止修改c_str指向的值。編譯器不會因爲const_cast而抱怨,但它仍然是錯誤的。