2009-12-04 28 views
79

Mã sau đây cho tôi lỗi phân đoạn khi chạy trên máy 2Gb, nhưng hoạt động trên máy 4GB.Lỗi phân đoạn trên các kích thước mảng lớn

int main() 
{ 
    int c[1000000]; 
    cout << "done\n"; 
    return 0; 
} 

Kích thước của mảng chỉ là 4Mb. Có giới hạn về kích thước của một mảng có thể được sử dụng trong c + + không?

Trả lời

93

Có thể bạn đang gặp phải tình trạng tràn ngăn xếp ở đây. Mảng quá lớn để vừa với không gian địa chỉ ngăn xếp của chương trình.

Nếu bạn phân bổ mảng trên heap, bạn nên ổn, giả sử máy của bạn có đủ bộ nhớ.

int* array = new int[1000000];

Nhưng hãy nhớ rằng điều này sẽ yêu cầu bạn phải delete[] mảng. Giải pháp tốt hơn là sử dụng std::vector<int> và đổi kích thước thành 1000000 yếu tố.

+0

Cảm ơn câu trả lời, nhưng bạn có thể giải thích cho tôi lý do mảng được cấp phát trên ngăn xếp và tại sao không nằm trong bộ nhớ chương trình chính. – Mayank

+9

Mã đã cho phân bổ trên ngăn xếp vì nó được chỉ định dưới dạng một mảng với số lượng phần tử không đổi tại thời gian biên dịch. Giá trị chỉ được đặt trên heap với malloc, mới, vv –

+3

Tất cả các biến tự động được phân bổ trên ngăn xếp. Nếu bạn nhìn vào disasseble bạn sẽ thấy kích thước của các biến địa phương của bạn trừ từ con trỏ ngăn xếp.Khi bạn gọi malloc hoặc calloc hoặc bất kỳ bộ nhớ fuctions các cuộc đấu giá đi và tìm khối của bộ nhớ đủ lớn để sataisfy reqest của bạn. – rerun

2

Mảng đang được cấp phát trên ngăn xếp trong trường hợp này cố gắng phân bổ một mảng có cùng kích thước bằng cách sử dụng phân bổ.

46

Trong đối tượng địa phương C hoặc C++ thường được phân bổ trên ngăn xếp. Bạn đang phân bổ một mảng lớn trên ngăn xếp, nhiều hơn ngăn xếp có thể xử lý, do đó bạn đang nhận được một số stackoverflow.

Không cấp phát cục bộ đó trên ngăn xếp, thay vào đó hãy sử dụng một số địa điểm khác. Điều này có thể đạt được bằng cách tạo đối tượng toàn cầu hoặc phân bổ nó trên toàn cầu heap. Biến toàn cầu là tốt, nếu bạn không sử dụng từ bất kỳ đơn vị biên dịch nào khác. Để đảm bảo điều này không xảy ra một cách tình cờ, hãy thêm một bộ lưu trữ tĩnh, nếu không thì chỉ cần sử dụng heap.

này sẽ phân bổ trong phân khúc BSS, mà là một phần của đống:

static int c[1000000]; 
int main() 
{ 
    cout << "done\n"; 
    return 0; 
} 

này sẽ phân bổ trong phân khúc DỮ LIỆU, mà là một phần của đống quá:

int c[1000000] = {}; 
int main() 
{ 
    cout << "done\n"; 
    return 0; 
} 

Điều này sẽ phân bổ tại một số vị trí không xác định trong heap:

int main() 
{ 
    int* c = new int[1000000]; 
    cout << "done\n"; 
    return 0; 
} 
+0

Nếu bạn sử dụng mẫu thứ ba, phân bổ trên heap, đừng quên xóa [] con trỏ ở một số giai đoạn hoặc bạn sẽ bị rò rỉ bộ nhớ. Hoặc nhìn vào con trỏ thông minh. – meowsqueak

+6

@meowsqueak Tất nhiên là thực hành tốt để 'xóa' ở mọi nơi bạn phân bổ bằng' mới'. Nhưng nếu bạn chắc chắn rằng bạn chỉ cấp phát bộ nhớ một lần (như trong chính), nó là hoàn toàn không cần thiết - bộ nhớ được đảm bảo sẽ được giải phóng tại lối ra của chính ngay cả khi không rõ ràng 'xóa'. – hirschhornsalz

+0

'at'drhirsch (làm thế nào để bạn làm một nhân vật tại anyway?) - vâng, bình luận công bằng. Khi OP xuất hiện mới với ngôn ngữ tôi chỉ muốn đảm bảo rằng họ, và bất cứ ai khác nhìn thấy câu trả lời hay của bạn, đã nhận thức được ý nghĩa của tùy chọn thứ ba nếu được sử dụng nói chung. – meowsqueak

2

Vì bạn lưu trữ mảng trong sta ck. Bạn nên lưu trữ nó trong heap. Xem this link để hiểu khái niệm về đống và ngăn xếp.

6

Ngoài ra, nếu bạn đang chạy trong hầu hết các hệ thống UNIX & Linux bạn có thể tạm thời tăng kích thước stack bằng lệnh sau:

ulimit -s unlimited 

Nhưng hãy cẩn thận, bộ nhớ là một nguồn lực hạn chế và với sức mạnh lớn đến lớn trách nhiệm :)

+0

Đây là giải pháp nhưng tôi khuyên tất cả phải cực kỳ thận trọng khi loại bỏ giới hạn mặc định này trên kích thước ngăn xếp của chương trình. Bạn sẽ trải nghiệm không chỉ giảm hiệu năng nghiêm trọng mà hệ thống của bạn có thể gặp sự cố. Ví dụ tôi đã cố gắng sắp xếp một mảng với 16 000 000 yếu tố nguyên với quicksort trên một máy tính với 4GB RAM và hệ thống của tôi đã gần như bị giết. LOL – rbaleksandar

+0

@rbaleksandar Tôi nghĩ rằng bạn ~ 16MB chương trình gần như giết máy của bạn bởi vì bạn đang làm việc với một số bản sao của mảng (có thể là một cho mỗi cuộc gọi chức năng?) Hãy thử một bộ nhớ nhiều hơn thực hiện nhận thức;) – RSFalcon7

+0

Tôi khá chắc chắn xử lý mảng không sao vì tôi đi qua tham chiếu chứ không phải bằng giá trị. Điều tương tự cũng xảy ra với bubbleort. Địa ngục, ngay cả khi thực hiện của tôi về quicksort sucks bubbleort là một cái gì đó mà bạn không thể thực hiện không chính xác. LOL – rbaleksandar

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