Câu hỏi C ++ vector :: rõ ràng


vector <weight> decoy;

void clear_decoy() {  

    decoy.clear();   

    vector<weight> (decoy).swap(decoy);  
}

Trong phương pháp trên clear_decoy()cái gì vector<weight> (decoy).swap(decoy);  có nghĩa là xin vui lòng?

Liệu phương pháp có rõ ràng không decoy hay không? Cảm ơn!


22
2017-08-13 14:19


gốc


Hãy nhớ chấp nhận câu trả lời mà bạn cảm thấy là tốt nhất bằng cách nhấp vào dấu kiểm của họ - Nick T


Các câu trả lời:


Nó tạo ra một vectơ mới của Weight các đối tượng (sẽ trống) và hoán đổi nó với decoy.

Lý do cho điều này là theo mặc định, std::vector<t>::clear thường không thực sự giảm dung lượng được sử dụng bởi một vectơ, nó chỉ phá hủy tất cả các đối tượng có trong đó. Bằng cách này, vector có chỗ để lưu trữ nhiều đối tượng hơn mà không cần phân bổ lại trong tương lai.

Đôi khi, tuy nhiên, bạn muốn cắt giảm dung lượng trong vectơ. Trao đổi với một vectơ mới được tạo ra (cho đến khi kết thúc dòng của nó, và do đó bị phá hủy ở đó) giải phóng tất cả bộ nhớ được phân bổ bởi vectơ.


20
2017-08-13 14:22



Ôi trời ơi! C ++ yêu của tôi, bạn gây rắc rối cho những người yêu bạn bằng cách thông minh hơn chúng ta. - Agnel Kurian
Được thông minh có một chi phí xã hội. - Klaim
Điều này là rất C + + y. C ++ bộc lộ khả năng quản lý bộ nhớ ở đây để bạn có cơ hội tùy chỉnh mọi thứ cho nhu cầu của mình. Theo mặc định C ++ cố gắng để nhanh như nó có thể, và vì vậy nếu bạn không làm theo mã này bạn sẽ nhận được mã nhanh hơn. Trong trường hợp bạn có một vectơ rất lớn và bạn loại bỏ nhiều phần tử của nó thì bạn có thể sử dụng thành ngữ này để giải phóng tài nguyên miễn phí cho hệ điều hành, về chi phí của tốc độ. Thông thường bạn không muốn làm điều đó (tức là, không sửa chữa những gì không bị hỏng). - wilhelmtell


Tôi chưa từng thấy biểu mẫu đó trước đây.

Tôi đã thấy nó được viết như sau:

vector<weight>().swap(decoy);

Điều đó có nghĩa là "tạo một vectơ trống mới, và hoán đổi nó với vectơ trống.

vector<weight> (decoy).swap(decoy);

Để hiểu điều đó, hãy đột nhập vào các phần.

vector<weight>(decoy)  tạo ra một vectơ mới (với nội dung của nó được sao chép từ decoy giờ trống). Các vector mới là một tạm thời độc lập, vì vậy chúng ta hãy giả vờ tên của nó là newvector.

newVector.swap(decoy);  hoán đổi vector mới với decopy.

(Cập nhật mỗi nhận xét để sửa lỗi)


22
2017-08-13 14:23



1 để đề xuất một cấu trúc phổ biến hơn (và nhiều hơn nữa) chung của cùng một thứ. - Billy ONeal
Đó phải là vector<weight>().swap(decoy). Bạn có thể gọi các hàm thành viên trên các thời gian, nhưng bạn không thể chuyển chúng thành các đối số tham chiếu không phải const. - Mike Seymour
+1 Tôi là một kẻ đánh máy xấu. :) - John Dibling
Tôi nghĩ rằng C ++ 0x STL định nghĩa thêm một shrink phương pháp để giảm lượng bộ nhớ dựa trên kích thước thực tế ... hoặc là suy nghĩ mơ ước này? - Matthieu M.
@Matthieu: vâng, nó được gọi là shrink_to_fit, nhưng việc thực hiện không phải tôn trọng nó. - Mike Seymour


Mã đó là một nỗ lực không thành công để sử dụng một thủ thuật thông thường để đảm bảo bộ nhớ được phân bổ bởi vectơ được giải phóng. Nó có thể hoặc có thể không thực sự làm điều đó, tùy thuộc vào việc nhà xây dựng bản sao của vector có phân bổ bộ nhớ cho phù hợp với kích thước của vectơ khác hay dung lượng của nó hay không.

Để giải phóng bộ nhớ đáng tin cậy, hãy sử dụng như sau:

void clear_decoy() {  
    vector<weight>().swap(decoy);  
}

Điều này tạo ra một vector trống tạm thời (với ít hoặc không có bộ nhớ được cấp phát), hoán đổi nó với decoy để bộ nhớ hiện thuộc sở hữu của tạm thời, sau đó phá hủy tạm thời, giải phóng bộ nhớ.


10
2017-08-13 14:31



Điểm tuyệt vời. - John Dibling
Trong khi điều này là đúng, thì việc triển khai STL không lành mạnh sẽ phân bổ dựa trên khả năng ở đây. - Billy ONeal
@Billy: Thật vậy; điệu nhảy rõ ràng-copy-swap vụng về rất có khả năng hoạt động, nhưng phiên bản đơn giản hơn được đảm bảo hoạt động. - Mike Seymour


clear loại bỏ tất cả các mục từ vectơ, nhưng có thể không nhất thiết phải giải quyết không gian. Thành ngữ hoán đổi này khôi phục vectơ để không có không gian được cấp phát.


6
2017-08-13 14:21



Thực ra clear  có thể deallocate không gian vector chiếm. Nhưng nó không có đến. Nó thường không có trong hầu hết các triển khai STL mặc dù. - Billy ONeal
@Billy ONeal: Cảm ơn. Tôi đã chỉnh sửa câu trả lời của mình. - Fred Larson


Như 0A0D đề cập, hiệu quả của swap là trao đổi bộ nhớ kiểm soát cơ bản giữa hai vectơ. Nhưng điều này đảm bảo giải thích thêm một chút.

Khi bạn clear một vector, các yếu tố được loại bỏ khỏi nó ít nhất là như xa như các lập trình viên là có liên quan. size() trở thành số không và capacity() có thể hoặc không thể thay đổi. Nhưng tiêu chuẩn không đảm bảo rằng bộ nhớ được sử dụng bởi vectơ sẽ thực sự được trả về hệ điều hành. Vì vậy, nếu bạn có 1000 phần tử trong vectơ trước clear() và mỗi bộ nhớ 1000 byte, sau clear() destructor của mỗi phần tử được gọi, nhưng vectơ vẫn có thể giữ trên một phân bổ 1.000.000 byte.

Điều này đôi khi không mong muốn. Các 'trao đổi lừa' bạn lưu ý ở trên có tác dụng trao đổi bộ nhớ kiểm soát giữa hai vectơ. Vì thế decoy kết thúc với thiết lập lại bộ nhớ được kiểm soát.

Đây là những gì đang xảy ra từng bước:

  1. decoy các phần tử là mỗi phần tử erased. Các destructor của các phần tử là được gọi là và của vectơ size() trở thành số không. Bộ nhớ thực tế có thể không được deallocated.
  2. Một vectơ mới được xây dựng trên ngăn xếp (vector<weight> (decoy)) và các yếu tố từ decoy được sao chép vào nó. Vì decoy chỉ là clear()ed, không có phần tử nào được sao chép vào vectơ tạm thời. Tuy nhiên, hãy xem chỉnh sửa bên dưới. Bạn không biết rằng bộ nhớ được kiểm soát không đổi chỗ.
  3. Các vector tạm thời và decoybộ nhớ của được đổi chỗ (.swap(decoy);) dẫn đến decoy bị xóa và bộ nhớ được chuyển sang tạm thời.
  4. Tạm thời rơi ra khỏi ngăn xếp, dẫn đến bộ nhớ của nó đang được deallocated.

Điều này được gọi là "lừa trao đổi".

EDIT: Như Mike đề cập, lập trình ban đầu là làm sai. Tạm thời không nên được xây dựng dựa trên decoy, nó chỉ nên được xây dựng mặc định. Bạn không biết chắc chắn rằng swap() sẽ chỉ sao chép các phần tử chứ không phải bộ nhớ được kiểm soát bên dưới.


3
2017-08-13 14:32



+1 Giải thích tuyệt vời


Với rõ ràng,

Tất cả các phần tử của vector là   bị bỏ rơi: những kẻ hủy diệt của họ được gọi,   và sau đó chúng bị xóa khỏi   container vector, để lại   container có kích thước bằng 0.

Hoán đổi chỉ hoán đổi hai vectơ,

Hoán đổi nội dung

Trao đổi nội dung của véc tơ bằng   nội dung của vec, cái khác   vector cùng loại. Kích thước có thể   khác nhau.

Sau cuộc gọi đến thành viên này   chức năng, các yếu tố trong này   container là những người trong vec   trước cuộc gọi và các yếu tố của   vec là những người trong đó. Tất cả các   trình lặp, tham chiếu và con trỏ   vẫn hợp lệ cho các vectơ đổi chỗ.

Có vẻ như bạn đang trao đổi không có gì thực sự và chỉ phục hồi để phân bổ mặc định. Rõ ràng có thể deallocate nhưng đôi khi nó không. Bạn không chỉ giảm kích thước mà còn làm giảm không gian được phân bổ bằng câu lệnh hoán đổi.


1
2017-08-13 14:20



bộ nhớ được phát hành? - ladyfafa
@ladyfafa: Với tuyên bố hoán đổi, số lượng không gian được phân bổ bị giảm. Đó là phần đẹp của vectơ.
tôi hiểu rồi, cảm ơn !! - ladyfafa