2017-08-01 20 views
7

Các đoạn mã sau biên dịch và chạy mà không có lỗi và với sản lượng dự kiến:Return C-string địa phương cho chức năng với C++ chuỗi giá trị trả về

#include <string> 
#include <iostream> 
using namespace std; 

string getString() 
{ 
    char s[] = "Hello world!"; 
    return s; 
} 

int main() 
{ 
    cout << getString() << endl; 
} 

Câu hỏi của tôi là, sẽ này luôn làm việc? Thông thường nếu bạn trả về một chuỗi C đã được khai báo cục bộ, bạn có thể chạy vào một số hành vi không xác định, nhưng trong trường hợp này vẫn còn là một vấn đề vì nó được chạy qua hàm tạo chuỗi và (có lẽ) được sao chép vào bộ nhớ động?

+0

Một trong những lý do chính 'std :: string' được thêm vào thư viện chuẩn - nó có thể được sử dụng như một kiểu được nhúng như' int' và 'double', do đó, có vâng trả lại' std :: string' bởi giá trị. – Slava

+1

Bạn có biết rằng chuỗi rác có thời gian lưu trữ tĩnh: [cpp-ref] (http://en.cppreference.com/w/cpp/language/string_literal). Vì vậy, nếu chuỗi c của bạn chỉ trỏ đến một chuỗi literral như trong 'const char * s =" Hello World "' bạn có thể trả lại nó một cách an toàn từ hàm của bạn, vì s là một con trỏ trỏ tới một đối tượng có thời gian lưu trữ tĩnh. Đây là lý do tại sao 'std :: except :: what()' hoặc 'type_info :: name()' trả về một c-string – Oliv

+0

@Oliv đó là một thực tế gọn gàng nhưng đây chỉ là một ví dụ, trong chương trình thực sự của tôi chuỗi C là được tạo tại thời gian chạy –

Trả lời

12
return s; 

dòng Đó là tương đương với:

return std::string(s); 

Và đó sẽ làm cho một sao chép của chuỗi, vì vậy nó là tốt.

tham khảo:http://en.cppreference.com/w/cpp/string/basic_string/basic_string (constructor # 5)

Constructs chuỗi với các nội dung khởi tạo với một bản sao của chuỗi ký tự null-chấm dứt được trỏ đến bởi s.

Chỉnh sửa: Một chi tiết khác. Bạn đề cập đến

được sao chép vào bộ nhớ động?

Và câu trả lời có lẽ, có lẽ, nó không thực sự quan trọng.

Ngữ nghĩa được cung cấp bởi std::string không có đặc điểm kỹ thuật về điều này, nó chỉ đảm bảo rằng nó có thể được sao chép/di chuyển xung quanh và truy cập trong một vấn đề nhất quán. Làm thế nào nó acheives này là đến triển khai thư viện.

Trong thực tế, việc triển khai phổ biến của std::string sử dụng một cái gì đó gọi là "S mall S Tring O ptimization". Trong đó chuỗi dưới một độ dài nhất định được lưu trữ trong chính đối tượng chuỗi.

+0

Đối tượng 'std :: string' tạm thời được trả về được xây dựng (không được sao chép!) từ mảng' s'. – Buster

+1

Tôi nghĩ rằng bạn hiểu sai, hàm tạo của 'std :: string' sao chép nội dung của chuỗi được chỉ bởi' s'. 's' vẫn là một chuỗi, một chuỗi c, nhưng vẫn là một chuỗi. – Frank

+0

Có, đủ công bằng. Không thể phủ nhận rằng "một _copy_ của chuỗi" được thực hiện, theo nghĩa byte của chuỗi sẽ được sao chép. – Buster

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