30/09/2018, 17:13

Giá trị của string::capacity là khác nhau trong VS và Codeblock?

Hôm nay tôi có đọc qua phần chuỗi trong C++. Tôi thực hành trên 2 công cụ là VS và CodeBlock.
code:

#include  <iostream>
#include  <string>
using namespace std;
void main(){
	string str="abcd";
	cout<< str.capacity();

	system("pause");
}

Thật bất ngờ khi mà 2 công cụ này lại trả về 2 kết quả khác nhau. VS trả về là 15, còn Codeblock trả về 4. Mọi người có thể giúp tôi giải đáp sự khác nhau này được không? Xin cảm ơn!!!

huong viết 19:21 ngày 30/09/2018

Chắc do cách làm việc trên trình biên dịch của bác bill gate khác với cách làm việc của gcc.
Mà mình thấy kết quả của hàm này không ảnh hưởng nhiều. Hàm này trả về số byte (hay là so kí tự không biết nữa),đại để là kích thước của bộ nhớ đang chứa chuỗi,và nó thay đổi theo chuỗi đang chứa (Tất nhiên là phải lớn hơn hoặc bằng chuỗi đang chứa). Hình như bộ nhớ này được nhân 2 mỗi khi thêm thì phải.
Chắc visual cấp it nhất 15 byte mỗi khi khởi tạo chuỗi ,còn gcc thì cấp theo chuỗi được khởi tạo. Nếu thay đổi mà làm bộ nhớ không đủ thì nó nhân 2 lên.
vd bác cộng thêm 1 chữ vào str là capacity ở gcc lên 8 . tiếp tục thêm nhưng vẫn nhỏ hơn 8 thì capacity vẫn là 8.
Vậy tóm lại chắc là do

  • bill cấp cho chuỗi it nhất 15byte
  • gcc tùy vào chuỗi khởi tạo mà cấp
    Ah còn cái này nữa e cung ko biết sao: bên bill thường x2 +1 nếu thay đổi bộ nhớ chứa chuỗi,gcc vẫn x2

Tất nhiên e cũng trình bày theo cách hiểu của e. các bác vào góp ý thêm a

Minh Hoàng viết 19:20 ngày 30/09/2018

có vẻ giống kiểu tạo padding của container vector nhỉ

Mai Anh Dũng viết 19:16 ngày 30/09/2018

Cảm ơn @ngvandung đã chia sẻ một vấn đề rất thú vị nhé. Hầu hết mọi người chỉ thử với compiler quen thuộc của mình mà không thử tìm hiểu với compiler khác.

Theo như thông tin Đạt đọc được về string::capacity thì nó không nhất thiết phải bằng chiều dài của string hiện có. Nó có thể lớn hơn để đỡ mất công phải cấp thêm bộ nhớ khi ta tăng kích thước chuỗi.

This capacity is not necessarily equal to the string length. It can be equal or greater, with the extra space allowing the object to optimize its operations when new characters are added to the string.

Tùy chọn này do người lập trình compiler quyết định. CodeBlock sử dụng MinGW tương đương với g++. Trong khi VS sử dung cl.exe là phiên bản C++ compiler của Microsoft.

  • gcc tùy vào chuỗi khởi tạo mà cấp

Cái này cùng chưa chắc được. Trong ví dụ này ta thấy vậy. Nhưng theo Đạt nếu mình thử với kích thước lớn hơn của string, hoặc kích thước không phải là 2^n thử có lẽ g++ cũng cung cấp một phần “thừa” để tránh phải cấp vùng nhớ liên tục.

Ghi chú: Đạt mới thử với string “daynhauhoc” và g++ vẫn chỉ trả ra 10. Có lẽ phát biểu của @qhxh chính xác. Google thêm thì Đạt thấy có một trả lời có liên quan về vấn đề này: http://stackoverflow.com/a/9072702/1989112

Rằng giá trị của capacity không được định nghĩa trong chuẩn. Nên compiler sẽ quyết định

có vẻ giống kiểu tạo padding của container vector nhỉ

string cũng được coi là containter

The standard string class provides support for such objects with an interface similar to that of a standard container of bytes

huong viết 19:20 ngày 30/09/2018

có vẻ giống kiểu tạo padding của container vector nhỉ

Bác này lại nhắc đến cái vector gì gì đó làm e cay cú. Chiều vừa thi cuối kì vào phần vector mà chả biết cái gì

Minh Hoàng viết 19:14 ngày 30/09/2018

The standard string class provides support for such objects with an interface similar to that of a standard container of bytes

thank anh. Không hay dùng string lắm. Em thấy cái list member function của nó cũng giống y chang
như của vector.
không biết các c++ sau này có định nghĩa không. Trong đây, ổng nói là của C++03

Bác này lại nhắc đến cái vector gì gì đó làm e cay cú. Chiều vừa thi cuối kì vào phần vector mà chả biết cái gì

mình thì thi cuối kì linked list :D.


cảm ơn bạn ngvandung đã test thử nhá

Nguyễn Văn Dũng viết 19:20 ngày 30/09/2018

Cảm ơn bạn Đạt rất nhiều. Mình đã quyết định từ bỏ một số thứ và theo đuổi đam mê lập trình. Không biết 10 năm nữa sẽ ra sao. Có gì mong mọi người chỉ bảo.

Gió viết 19:29 ngày 30/09/2018

Cái capacity này cũng giống vector 1 chút. Nhưng thường vector sẽ theo kiểu array doubling nên capacity là một lũy thừa của 2. Còn string thì nó có thể bắt đầu khác một chút, nhưng thuật toán nối chuỗi push_back operator+= đều dựa trên thuật toán trên.

Về cơ chế của vector bạn có thể tham khảo https://github.com/boconganh/algorithm/blob/master/c/array-double.c

huong viết 19:20 ngày 30/09/2018

. Mình đã quyết định từ bỏ một số thứ và theo đuổi đam mê lập trình.

Bác có từ bỏ gấu thì để lại cho e

Bài liên quan
0