2010-03-25 52 views
22

Bây giờ tôi có một hàm phải trả về một chuỗi. Tôi đã thấy một triển khai cụ thể trong đó anh ta trả về một const char * từ hàm.Bạn có nên trả về "const char *" từ một hàm không?

Something như thế này:

const char * GetSomeString() 
{ 
    ........ 
    return somestlstring.c_str(); 
} 

SomeOtherFoo() 
{ 
    const char * tmp = GetSomeString(); 
    string s = tmp; 
} 

Bây giờ tôi cảm thấy có cái gì đó có khả năng sai với điều này. Đường ruột của tôi có đúng không? hoặc Đây có phải là mã hoàn toàn an toàn không?

Vui lòng cho tôi đề xuất ur. Tôi có một cảm giác trở lại const char * Bằng cách này có thể dẫn đến tàn phá ..

Cảm ơn, Arjun

Trả lời

26

Tùy thuộc vào những gì somestlstring là gì và những gì đang được thực hiện ở đó.

Nếu đó là biến cục bộ, bạn sẽ trả về con trỏ vào bộ nhớ đang được giải phóng khi hoàn thành GetSomeString, do đó, đó là một con trỏ lơ lửng và lỗi.

Tất cả sẽ được lưu lại trong vòng đời somestlstring và các thao tác bạn thực hiện trên đó. Con trỏ được trả về bởi .c_str() được đảm bảo chỉ hợp lệ cho hoạt động đột biến tiếp theo trong chuỗi. Vì vậy, nếu một cái gì đó thay đổi somestlstring từ các cuộc gọi đến .c_str() và trước khi s được xây dựng, bạn sẽ ở trong vùng hành vi không xác định.

6

Nếu bạn hỏi về tuổi thọ của const char * được trả về bởi hàm std::stringc_str(), nó hợp lệ cho đến khi bạn sửa đổi chuỗi bạn đã nhận được từ hoặc cho đến khi chuỗi bị hủy. Trả lại từ một chức năng là OK (mặc dù tôi sẽ nói không thực hành tuyệt vời), miễn là bạn phải chịu đựng hai sự kiện trong tâm trí.

2

Nó không tuyệt vời - bao lâu bộ nhớ cho chuỗi của bạn dính xung quanh? Ai chịu trách nhiệm xóa nó? Nó có cần phải bị xóa không?

Bạn nên quay trở lại một đối tượng chuỗi chịu trách nhiệm phân bổ và giải phóng bộ nhớ chuỗi - đây có thể là std :: string hoặc QString (nếu bạn đang sử dụng Qt) hoặc CString (nếu bạn đang sử dụng MFC/ATL).

trên ghi chú hơi khác, chuỗi của bạn có bao giờ là unicode không? Hầu hết các lớp chuỗi có thể xử lý minh bạch với dữ liệu unicode, nhưng const char sẽ không ...

1

Nó phụ thuộc vào vị trí biến số somestlstring.

Nếu đó là miền địa phương biến thành hàm GetSomeString() thì điều này rõ ràng là sai. Thật vậy, biến số somestlstring bị phá hủy ở cuối hàm, và do đó, const char * trỏ đến một thứ không tồn tại nữa.

Nếu đó là biến toàn cầu, thì mã này là đúng.

3

Điều này phù hợp với các điều kiện @Neil được xây dựng trên. Tuy nhiên một cách tốt hơn sẽ được trả về một tham chiếu đến chuỗi

string const& GetSomeString() 
{ 
    ........ 
    return somestlstring; 
} 

string s = GetSomeString(); 

Tuy nhiên hãy nhớ rằng'somestlstring` không phải là một biến tự động địa phương nhưng được lưu trữ ở một nơi khác trong một không gian tên hoặc một lớp học.Nếu không, bạn có thể trả về chuỗi giá trị

string GetSomeString() 
{ 
    ........ 
    return somestlstring; // can be a local automatic variable 
} 

string s = GetSomeString(); 
+2

Trừ khi somestlstring là một địa phương trong phạm vi chức năng. :-) – Konrad

+2

@Konrad chắc chắn, nhưng tôi cũng nói rằng trong câu trả lời của tôi ngay sau khi tôi cho thấy mã. :) –

1

Để thêm một số kịch bản mà điều này sẽ là ok:

  • somestlstring là một biến toàn cầu khởi tạo trong cùng một đơn vị dịch (cpp) như GetSomeString ()
  • somestlstring là thành viên lớp không tĩnh và GetSomeString là thành viên của lớp đó. Trong trường hợp đó, thời gian tồn tại của con trỏ được trả về phải được ghi lại (về cơ bản - như những người khác đã nói - cho đến khi thay đổi strign hoặc đối tượng bị hủy)
  • bạn đang trả về một ký tự char * thành chuỗi được khởi tạo theo thời gian hoặc biên dịch
Các vấn đề liên quan