2012-02-03 31 views
7

thể trùng lặp:
std::string and its automatic memory resizingCác chuỗi C++ được lưu trữ như thế nào?

Tôi chỉ tò mò, làm thế nào được chuỗi được lưu trữ trong bộ nhớ? ví dụ: khi tôi làm điều này:

string testString = "asd"; 

nó phân bổ 4 byte, phải không? a + s + d + \0.

Nhưng sau đó, khi tôi muốn gán một số văn bản mới cho chuỗi này, nó hoạt động, nhưng tôi không hiểu làm thế nào. Ví dụ: tôi thực hiện điều này:

testString = "123456789" 

Bây giờ phải dài 10 byte. Nhưng nếu không có không gian cho chuỗi đó thì sao? chúng ta hãy nói rằng thứ năm + thứ sáu byte từ đầu chuỗi được thực hiện bởi một số 2 ký tự khác. CPU xử lý nó như thế nào? Nó tìm thấy vị trí hoàn toàn mới trong bộ nhớ mà chuỗi đó phù hợp?

+0

Có thể không trùng lặp chính xác, câu hỏi ban đầu đã biết rằng bộ nhớ được phân bổ động bởi chuỗi, mà tôi không chắc chắn là trường hợp ở đây. Dù sao tôi sẽ không bỏ phiếu để mở lại. –

Trả lời

12

Điều này phụ thuộc vào việc triển khai thực hiện, nhưng ý tưởng chung là lớp chuỗi sẽ chứa một con trỏ tới vùng bộ nhớ nơi lưu trữ nội dung thực tế của chuỗi. Hai triển khai phổ biến là lưu trữ 3 con trỏ (bắt đầu của vùng được phân bổ và dữ liệu, kết thúc dữ liệu, kết thúc vùng phân bổ) hoặc con trỏ (bắt đầu vùng và dữ liệu được phân bổ) và hai số nguyên (số ký tự trong chuỗi và số phân bổ byte).

Khi dữ liệu mới được nối vào chuỗi, nếu nó khớp với vùng được phân bổ, nó sẽ chỉ được ghi và kích thước/đầu của con trỏ dữ liệu sẽ được cập nhật tương ứng. Nếu dữ liệu không vừa trong vùng, bộ đệm mới sẽ được tạo và dữ liệu được sao chép.

Cũng lưu ý rằng nhiều triển khai có tối ưu hóa cho các chuỗi nhỏ, trong đó lớp chuỗi chứa một bộ đệm nhỏ.Nếu nội dung của chuỗi phù hợp trong bộ đệm, thì không có bộ nhớ nào được cấp động và chỉ bộ đệm cục bộ được sử dụng.

+1

Vâng 3 con trỏ là 24 byte (trên vòm 64 bit). Đó là một chuỗi có kích thước hợp lý nếu bạn chỉ viết trên con trỏ bằng cách sử dụng không gian của họ làm bộ đệm. –

+0

cảm ơn, tôi nghĩ rằng tôi nhận được nó ngay bây giờ – user1145902

+1

@LokiAstari: Bạn sẽ phải thêm một lá cờ phụ ở đâu đó để xác định xem bộ nhớ được sử dụng như một bộ đệm hay không. Nhưng nó là một giả định hợp lý rằng nó là * rẻ * để tái sử dụng các con trỏ cho một tối ưu hóa bộ đệm nhỏ. –

2

string là một đối tượng, không chỉ là một số vị trí bộ nhớ. Nó tự động phân bổ bộ nhớ khi cần thiết.

Nhà điều hành = bị quá tải; khi bạn nói testString = "123456789"; phương thức đang được gọi và giao dịch với số const char * bạn đã chuyển.

+0

Nếu tôi không nhầm, 'std :: string' không phải là một đối tượng. – jrok

+0

để ký tự trong chuỗi không phải được đặt hàng trong byte bộ nhớ bằng byte (như mảng bình thường) nhưng chúng có thể được lưu trữ ở một số vị trí ngẫu nhiên? – user1145902

+3

@jrok: Dường như bạn đang nhầm lẫn ... trừ khi bạn thực sự có nghĩa là 'std :: string' là một loại (instantiation của một mẫu) từ đó các đối tượng được instantiated ... –

2

Nó được lưu trữ với kích thước. Nếu bạn lưu trữ một chuỗi mới, nó sẽ tùy chọn deallocate bộ nhớ hiện có và phân bổ bộ nhớ mới để đối phó với sự thay đổi về kích thước.

Và nó không nhất thiết phân bổ 4 byte lần đầu tiên bạn chỉ định một chuỗi 4 byte cho nó. Nó có thể phân bổ nhiều không gian hơn (nó sẽ không phân bổ ít hơn).

3

string không phải là kiểu dữ liệu đơn giản như char *. Đó là một lớp , có chi tiết triển khai không nhất thiết phải hiển thị.

Trong số những thứ khác, string bao gồm bộ đếm để theo dõi mức độ lớn thực sự của nó.

char[] test = "asd";  // allocates exactly 4 bytes 
string testString = "asd"; // who knows? 

testString = "longer";  // allocates more if necessary 

Góp ý: viết một chương trình đơn giản và bước qua nó sử dụng một trình gỡ lỗi. Kiểm tra string và xem cách các thành viên riêng thay đổi khi giá trị được thay đổi.

+0

cảm ơn bạn, tôi sẽ thử nó – user1145902

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