2012-04-28 29 views
21

Hãy xem xét các đoạn mã sau:Trường hợp hiện std :: vector cấp phát bộ nhớ của nó?

#include <vector> 
using namespace std; 

void sub(vector<int>& vec) { 
    vec.push_back(5); 
} 

int main() { 
    vector<int> vec(4,0); 
    sub(vec); 
    return 0; 
} 

Giả sử "vec" không có không gian còn lại để lưu trữ 5 trong hàm "phụ", nơi nào nó cấp phát bộ nhớ mới?

Trong khung ngăn xếp của chức năng phụ? Trong trường hợp đó, 5 sẽ bị xóa ở cuối hàm phụ. Nhưng khung ngăn xếp của hàm chính không thể phát triển, vì khung ngăn xếp của hàm phụ nằm ở trên cùng của ngăn xếp tại thời điểm đó.
Có std :: vector phân bổ bộ nhớ cho các phần tử của nó trên heap không? Nhưng bộ nhớ heap miễn phí như thế nào? Nếu đó là một vector cục bộ trên ngăn xếp, khung ngăn xếp của một hàm bao gồm vectơ bị xóa ở cuối mà không báo hiệu vectơ mà nó sẽ bị xóa?

+0

Bạn có thể muốn xem phân bổ STL. – pmdj

+3

'sub (vector & vec)' được gọi là 'phụ (vec)' sẽ dễ đọc hơn;) – LihO

+0

** Nó cấp phát bộ nhớ tại Heap ** [std :: vector Implementation] (http: // codereview .stackexchange.com/questions/60484/stl-vector-implementation) –

Trả lời

31

Có std :: vector phân bổ bộ nhớ cho các thành phần của nó trên heap không?

Có. Hoặc chính xác hơn nó phân bổ dựa trên cấp phát bạn chuyển vào lúc xây dựng. Bạn đã không chỉ định một, vì vậy bạn sẽ có được cấp phát mặc định. Theo mặc định, điều này sẽ là the heap.

Nhưng bộ nhớ heap miễn phí như thế nào?

Thông qua destructor khi nó nằm ngoài phạm vi. (Lưu ý rằng con trỏ đến một vectơ nằm ngoài phạm vi sẽ không kích hoạt trình phá hủy). Nhưng nếu bạn đã vượt qua giá trị cho sub bạn muốn xây dựng (và sau đó hủy) một bản sao mới. 5 sau đó sẽ được đẩy trở lại bản sao đó, bản sao sẽ được làm sạch và véc tơ trong main sẽ bị ảnh hưởng.

+0

Tôi không thấy trang http://www.cplusplus.com/reference/std/memory/allocator/allocate/ đã đề cập gì về phân bổ mặc định trên heap? – athos

0

Vì bạn đã đặt địa chỉ phụ của vectơ trong heap, nó sẽ cấp phát trong heap. Nếu không có không gian còn lại, ngoại lệ nên được ném.

+2

Hoàn toàn không có liên kết giữa một vectơ trên heap, và nó phân bổ bộ nhớ của nó trên heap. –

+0

không nhận được những gì bạn muốn nói, plz exlpain. – Stefan

+0

Vectơ không nằm trên "đống", bất cứ điều gì có thể. Nó nằm trong ngăn xếp 'main'. – juanchopanza

16

Tất cả các container trong STL được tham số hoá với đối số mẫu, thường là đối số cuối cùng được gọi là A hoặc Allocator và mặc định để std::allocator<...> nơi ... đại diện cho loại giá trị được lưu trữ trong các thùng chứa.

Allocator là lớp được sử dụng để cung cấp bộ nhớ và xây dựng/phá hủy các phần tử trong vùng bộ nhớ này. Nó có thể cấp phát bộ nhớ từ một hồ bơi hoặc trực tiếp từ heap, tùy theo bạn xây dựng bộ cấp phát nào. Theo mặc định, std::allocator<T> là trình bao bọc đơn giản xung quanh ::operator new và do đó sẽ cấp phát bộ nhớ trên heap khi bạn phỏng đoán.

Bộ nhớ được phân bổ theo yêu cầu và được cấp phát lại ít nhất khi được gọi là destructor của vector. C++ 11 giới thiệu shrink_to_fit để phát hành bộ nhớ sớm hơn. Cuối cùng, khi vectơ vượt quá khả năng hiện tại của nó, một phân bổ mới (lớn hơn) được tạo ra, các đối tượng được chuyển đến nó, và phân bổ cũ được giải phóng.

Như tất cả các biến cục bộ, hàm hủy được gọi khi thực hiện đến cuối phạm vi mà nó đã được khai báo. Vì vậy, trước khi chức năng được thoát ra, các destructor vector được gọi là, và chỉ sau đó không ngăn xếp co lại và kiểm soát trả về cho người gọi.

2

Cũng lưu ý rằng vectơ của bạn (vec) là chính đối tượng.Nó nằm trên ngăn xếp và khi đối tượng này nằm ngoài phạm vi (kết thúc là main trong trường hợp của bạn), nó sẽ bị hủy. Bộ nhớ cho các phần tử được phân bổ trong quá trình khởi tạo đối tượng này và được giải phóng với sự hủy diệt của nó, là một ví dụ đáng yêu của thành phần RAII, vì việc quản lý tài nguyên của các phần tử được gắn với tuổi thọ của đối tượng vectơ.

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