2010-09-22 29 views
14

Chi phí trong cấu trúc chuỗi làm cho sizeof() là 32 là bao nhiêu?Tại sao sizeof (chuỗi) == 32?

+5

Nếu bạn mở tiêu đề '' của nền tảng, bạn có thể thấy chính xác lý do tại sao 'std :: string' là kích thước đó. @Queso: 'sizeof' mang lại kích thước của một đối tượng _in bytes_. –

+2

Nếu sizeof trả về số bit trong con trỏ thì trình biên dịch của bạn bị hỏng –

+0

@Queso: sizeof() trả về byte chứ không phải bit.Con trỏ 32 byte là địa chỉ 256 bit – mkb

Trả lời

39

Một số triển khai std::string lưu các chuỗi rất nhỏ trực tiếp trên ngăn xếp trong một mảng có kích thước tĩnh char thay vì sử dụng bộ nhớ heap động. Điều này cho phép tránh phân bổ đống cho nhiều đối tượng chuỗi nhỏ và cải thiện địa phương tham chiếu.

Hơn nữa, sẽ có thành viên std::size_t để lưu kích thước chuỗi và con trỏ (có thể chưa sử dụng, xem ở trên) vào bộ nhớ heap.

+1

Ah. Và tại sao điều này lại bị downvoted? –

+0

Có vẻ như tôi, nhưng tôi không cố tình làm điều đó. Xin lỗi vì điều đó! – Bill

+0

@Bill: không có mồ hôi! Đã xảy ra với tôi, quá. –

9

std::string thường chứa bộ đệm cho "tối ưu hóa chuỗi nhỏ" --- nếu chuỗi nhỏ hơn kích thước bộ đệm thì không yêu cầu phân bổ đống.

+0

Ở đâu "thông thường" == "trên Windows" ;-) –

+2

Trình biên dịch Windows không phải là duy nhất làm tối ưu hóa chuỗi nhỏ –

+0

Chắc chắn, nhưng nếu bạn không sẵn sàng đặt tên cho chúng thì rất khó để đánh giá liệu điều này là hành vi "điển hình" hoặc chỉ được gọi là trên cơ sở đó là hành vi của việc triển khai phổ biến (và có lẽ là những người khác). –

3

Tùy thuộc vào thư viện. Bạn không nên dựa vào kích thước của các đối tượng std::string vì nó có khả năng thay đổi trong các môi trường khác nhau (rõ ràng giữa các nhà cung cấp thư viện chuẩn khác nhau, nhưng cũng giữa các phiên bản khác nhau của cùng một thư viện).

Hãy nhớ rằng std::string triển khai được viết bởi những người đã tối ưu hóa cho nhiều trường hợp sử dụng, thường dẫn đến 2 biểu diễn nội bộ, một cho chuỗi ngắn (bộ đệm nội bộ nhỏ) và một cho chuỗi dài đệm). Chi phí liên quan đến việc giữ cả hai bên trong mỗi đối tượng std::string.

4

tôi đoán là:

class vector 
{ 
    char type; 
    struct Heap 
    { 
     char* start; 
     char* end; 
     char* allocatedEnd; 
    }; 
    struct Stack 
    { 
     char size; 
     char data[27]; 
    } 
    union 
    { 
     Stack stackVersion; 
     Heap heapVersion; 
    } version; 
}; 

Nhưng tôi đặt cược có hàng trăm cách để làm điều đó.

+0

awww ... no số lượng tham chiếu? những gì đã xảy ra để gấp? –

+0

@ErikAronesty Có một pha đã được tính toán tham chiếu với 'std :: string' nhưng rõ ràng là anh ta không hiệu quả lắm (có vài bài báo về nó qua nhiều năm) và thay vào đó việc tối ưu hóa chuỗi ngắn trở nên phổ biến. –

1

Hỏi: Tại sao một con chó màu vàng? A: Không nhất thiết.

Kích thước của đối tượng chuỗi (a?) Std :: là phụ thuộc vào việc triển khai thực hiện. Tôi chỉ cần kiểm tra MS VC++ 2010. Nó thực sự sử dụng 32 byte cho std :: string. Có một liên minh 16 byte có chứa văn bản của chuỗi, nếu nó sẽ phù hợp, hoặc một con trỏ để lưu trữ đống cho các chuỗi dài hơn. Nếu những người triển khai đã chọn giữ 18 byte chuỗi trong đối tượng chuỗi thay vì trên heap, kích thước sẽ là 34 byte. 16 byte còn lại bao gồm chi phí, chứa những thứ như độ dài của chuỗi và số lượng bộ nhớ hiện được phân bổ cho chuỗi.

Việc triển khai khác nhau có thể luôn phân bổ bộ nhớ từ heap. Việc triển khai như vậy chắc chắn sẽ yêu cầu ít bộ nhớ hơn cho đối tượng chuỗi.

2

Trong g ++ 5.2 (trong ví dụ g ++ 4.9, nó là khác nhau) một chuỗi được về cơ bản định nghĩa là:

class string { 
    char* bufferp; 
    size_t length; 
    union { 
    char local_buffer[16]; 
    size_t capacity; 
    }; 
}; 

Trên một máy tính thông thường này cho biết thêm lên đến 32 byte (8 + 8 + 16).

Định nghĩa thực tế là tất nhiên

typedef basic_string<char> string; 

nhưng ý tưởng là như nhau.

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