2017-01-08 19 views
7

Imagine mã như:Valgrind không hiển thị truy cập bộ nhớ không hợp lệ với c_str sử dụng không đúng cách()

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

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

Mã này có thể sụp đổ, phải không? Bởi vì chuỗi đó c điểm bị hủy. Nhưng chạy nó thông qua Valgrind không hiển thị bất kỳ truy cập bộ nhớ không hợp lệ. Tại sao? Tôi biết Valgrind không thể kiểm tra ngăn xếp, nhưng "ab" thực sự nằm trên heap, phải không?

+8

Tối ưu hóa chuỗi nhỏ. Hãy thử '" aaaaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbccccccccccccccccccccccc "' – StoryTeller

+8

Ý của bạn là gì "Bây giờ câu hỏi thực sự của tôi là sau đây"? Hãy hỏi một câu hỏi ** mới **. –

Trả lời

10

Mã này có thể gặp sự cố, phải không? Bởi vì chuỗi đó c điểm bị hủy.

Phải. Nó có hành vi không xác định, và điều đó có nghĩa là bất kỳ hành vi nào đều được cho phép. Crashing là một trong những điều có thể xảy ra. Tiếp tục như thể không có gì là sai, như xảy ra trên thực hiện của bạn, là một số khác.

Tôi biết Valgrind không thể kiểm tra ngăn xếp, nhưng "ab" thực sự nằm trên heap, phải không?

Không nhất thiết. Có một điều như là tối ưu hóa chuỗi ngắn, trong đó các chuỗi phù hợp trực tiếp trong chính đối tượng std::string được lưu trữ ở đó, để tránh chi phí phân bổ không cần thiết.

Nếu bạn nói rằng Valgrind không thể kiểm tra quyền truy cập ngăn xếp và trả lại std::string của bạn được lưu trữ trên ngăn xếp, điều đó sẽ giải thích tại sao Valgrind không thấy bất kỳ sự cố nào.

Các vấn đề liên quan