2017-01-08 49 views
7

想象這樣的代碼:Valgrind的未示出具有使用不當c_str()無效的內存訪問

string f() 
{ 
    string r = "ab"; 
    return r; 
} 

int main() { 
    const char *c = f().c_str(); 
    printf("%s.\n", c); 
    return 0; 
} 

該代碼可能會崩潰,是嗎?因爲c指向的字符串被破壞。但是,通過Valgrind運行它不會顯示任何無效的內存訪問。爲什麼?我知道Valgrind無法檢查堆棧,但「ab」實際上位於堆上,對嗎?

+8

小字符串優化。嘗試'「aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccc」' – StoryTeller

+8

你是什麼意思「現在我的實際問題是以下」?請提出**新問題**。 –

回答

10

此代碼可能會崩潰,對吧?因爲c指向的字符串被破壞。

沒錯。它有未定義的行爲,這意味着任何行爲都是允許的。崩潰是可能發生的事情之一。繼續下去,就好像沒有什麼不對,就像你實施時發生的那樣,是另一回事。

我知道Valgrind無法檢查堆棧,但「ab」實際上位於堆上,對嗎?

不一定。有如短字符串優化這樣的事情,其中​​直接適合於std::string對象本身的字符串存儲在那裏,以避免不必要的分配開銷。

如果您說Valgrind無法檢查堆棧訪問,並且您返回的std::string存儲在堆棧中,這就可以解釋Valgrind爲什麼沒有看到任何問題。