2012-04-04 43 views
45

Liệu sản phẩm C++ mã sau tốt được hình thành:std :: string :: c_str() và temporaries

void consumer(char const* p) 
{ 
    std::printf("%s", p); 
} 

std::string random_string_generator() 
{ 
    // returns a random std::string object 
} 

consumer(random_string_generator().c_str()); 

Tôi có vấn đề với nó là, sau khi tạo đối tượng std :: string tạm thời và tham gia con trỏ c_str(), không có gì ngăn cản std :: string object khỏi bị phá hủy (hoặc có thể tôi là sai?). Bạn có thể vui lòng chỉ cho tôi tiêu chuẩn, nếu mã là OK mặc dù tất cả mọi thứ. Nó hoạt động, khi tôi thử nghiệm với g ++.

Trả lời

56

Con trỏ được trả về bởi std::string::c_str() điểm đến bộ nhớ được duy trì bởi đối tượng chuỗi. Nó vẫn hợp lệ cho đến khi hàm không phải là const được gọi trên đối tượng chuỗi hoặc đối tượng chuỗi là bị hủy. Đối tượng chuỗi mà bạn quan tâm là tạm thời. Nó sẽ bị hủy ở cuối biểu thức đầy đủ, không phải trước và không sau. Trong trường hợp của bạn, kết thúc biểu thức đầy đủ là sau cuộc gọi tới consumer, vì vậy mã của bạn an toàn. Nó sẽ không được nếu consumer lưu con trỏ ở đâu đó, với ý tưởng sử dụng nó sau này.

Thời gian tồn tại của thời gian đã được xác định nghiêm ngặt kể từ C++ 98. Trước đó, nó thay đổi, tùy thuộc vào trình biên dịch và mã bạn đã viết sẽ không hoạt động với g ++ (trước năm 1995, khoảng — g ++ thay đổi điều này ngay lập tức khi ủy ban tiêu chuẩn bỏ phiếu). (Không có một std::string sau đó một trong hai, nhưng vấn đề tương tự ảnh hưởng đến bất kỳ người sử dụng viết chuỗi lớp.)

18

Các tạm std::string 's đời kéo dài chỉ vượt ra ngoài điểm mà consumer lợi nhuận, vì vậy nó là an toàn để sử dụng bất cứ điều gì trên đó chuỗi trực tiếp từ bên trong consumer. không OK là lưu trữ giá trị c_str trả về và cố gắng sử dụng sau (tạm thời sẽ bị hủy và chúng tôi chỉ có thể đoán những gì bạn sẽ tìm thấy ở đầu kia của con trỏ).

+1

bạn có thể cung cấp một gợi ý liên quan đến việc C++ 03 hoặc C++ 11 tiêu chuẩn xin vui lòng? – user1095108

+3

Thời gian tồn tại tạm thời được xác định trong §12.2. (Mục 12 là có tiêu đề "Chức năng thành viên đặc biệt", không chính xác nơi bạn muốn mong đợi tìm kiếm thời gian tồn tại của thời gian, nhưng đó là nơi mà nó có.) –

+0

@ user1095108 và tuổi thọ của các đối số chức năng có thể thu được từ § 3.2.2 và §3.7.2 trong tiêu chuẩn C++ 03. – juanchopanza

5

Trả về tạm thời bởi hàm random_string_generator() có thể được sử dụng trong hàm consumer() một cách an toàn.

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