2012-07-04 22 views
5

Tôi đang viết một chuỗi lớp tương tự như std :: string cho bài tập về nhà, nhưng tôi không thể tìm ra cách trả về chuỗi c không gây rò rỉ bộ nhớ và được bảo đảm giữ nguyên cho đến khi nó không còn được sử dụng nữa. Tôi hiện có:Làm thế nào để std :: string :: c_str() trả về một chuỗi c không gây rò rỉ bộ nhớ hoặc nội dung chuỗi không xác định?

const char* string::c_str() 
{ 
    char c[_size+1]; 
    strncpy(c,_data,_size); 
    c[_size]='\0'; 
    return c; 
} 

nhưng nội dung bị ghi đè ngay sau khi được gọi. Nếu tôi phân bổ động, tôi sẽ bị rò rỉ bộ nhớ hoặc chỉ có một chuỗi c có thể tồn tại từ một chuỗi đã cho bất kỳ lúc nào. Làm thế nào tôi có thể tránh điều này?

+1

"* hoặc chỉ một chuỗi c có thể tồn tại từ một chuỗi đã cho bất kỳ lúc nào *" Đây là cách 'std :: string' hoạt động - vấn đề là gì? – ildjarn

+0

Nếu 'strncpy()' là câu trả lời, có lẽ bạn đang [hỏi sai câu hỏi] (http://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not- safer-strcpy.html). –

+0

Tôi không nhận ra nó chỉ tồn tại cho đến khi thay đổi. Nó bây giờ hoạt động trong thời gian O (1). –

Trả lời

7

Nhưng chuỗi được trỏ đến bởi c_str chỉ được xác định rõ ràng cho đến khi std::string được sửa đổi tiếp theo (hoặc bị hủy).

Một cách để đạt được điều này có thể chỉ đơn giản là trả về một con trỏ đến bộ đệm bên trong của bạn (giả sử nó được kết thúc bằng null). Hãy ghi nhớ rằng một tiêu chuẩn tuân thủ c_str phải hoạt động trong O (1) thời gian; do đó không được phép sao chép.

+1

Điều cần biết. Điều đó gần giống như bắt buộc thực hiện một số lớp 'std :: string', cụ thể là một mảng các ký tự. – alfC

4

Từ http://www.cplusplus.com/reference/string/string/c_str/:

Những điểm mảng trở lại một vị trí nội bộ với yêu cầu không gian lưu trữ cho chuỗi này của nhân vật cộng chấm dứt null-nhân vật của mình, nhưng các giá trị trong mảng này không nên được sửa đổi trong chương trình và chỉ được đảm bảo duy trì không thay đổi cho đến khi cuộc gọi tiếp theo đến chức năng thành viên không liên tục của đối tượng chuỗi.

0

Bộ đệm được trả lại bởi c_str() không được đảm bảo giữ nguyên hoặc thậm chí hợp lệ cho đến khi nó không còn được sử dụng nữa.

Chỉ đảm bảo duy trì trạng thái hợp lệ cho đến khi chuỗi std :: bị thay đổi theo bất kỳ cách nào.

Việc triển khai thực hiện thẳng về phía trước: chỉ giữ biểu diễn bên trong của chuỗi không được kết thúc tại mọi thời điểm và trả về một con trỏ tới biểu diễn nội bộ từ c_str().