2010-11-19 30 views
7

Mã này mang lại cho tôi Segmentation Fault khoảng 1/2 thời gian:Phân đoạn do thiếu bộ nhớ trong C

int main(int argc, char **argv) { 
    float test[2619560]; 
    int i; 
    for(i = 0; i < 2619560; i++) 
     test[i] = 1.0f; 
} 

tôi thực sự cần phải phân bổ một mảng lớn hơn nhiều, có một số cách để cho phép hệ điều hành để cho phép tôi có thêm bộ nhớ?

Tôi đang sử dụng Linux Ubuntu 9.10

Trả lời

22

Bạn đang tràn kích thước ngăn xếp tối đa mặc định là 8 MB.

Bạn có thể tăng kích thước ngăn xếp - ví dụ: 32 MB:

ulimit -s 32767 

... hoặc bạn có thể chuyển sang giao đất có malloc:

float *test = malloc(2619560 * sizeof test[0]); 
+2

Nếu bạn sử dụng malloc, bạn có thể kiểm tra mã nếu phân bổ thành công - tốt hơn nhiều so với chạy thông qua phân bổ và hy vọng nó không sụp đổ. (addendum, không quá nhiều bình luận @caf) –

+2

@Sam Dufel Hãy lưu ý rằng một số hệ thống (ví dụ: linux theo mặc định) có thể trả lại cho bạn một con trỏ không null từ malloc ngay cả khi bạn đã hết bộ nhớ - dẫn đến các sự cố tương tự khi bạn cố gắng truy cập vào bộ nhớ đó. – nos

+0

Có lẽ chính xác hơn khi nói rằng một số hệ thống tách các khái niệm phân bổ không gian địa chỉ ảo và cam kết lưu trữ sao lưu. – caf

6

Ngay bây giờ bạn đang phân bổ (hoặc ít nhất là cố gắng) 2619560*sizeof(float) byte trên stack. Ít nhất trong hầu hết các trường hợp điển hình, ngăn xếp có thể chỉ sử dụng một lượng bộ nhớ hạn chế. Bạn có thể thử xác định nó static thay vì:

static float test[2619560]; 

này được nó ra khỏi ngăn xếp, vì vậy nó thường có thể sử dụng bất kỳ bộ nhớ còn trống để thay thế. Trong các chức năng khác, xác định một cái gì đó như static thay đổi ngữ nghĩa, nhưng trong trường hợp của main nó làm cho sự khác biệt nhỏ (khác với khả năng lý thuyết chủ yếu của đệ quy main).

+0

Đệ quy 'chính', eh? Nghe có vẻ thú vị. – You

+0

@You: Đôi khi được sử dụng trong IOCCC hoặc chơi gôn mã. Nếu không, không quá nhiều (và không được phép trong C++). –

0

Đó là ngăn xếp chồng chéo. Bạn nên sử dụng chức năng malloc để có bộ nhớ lớn hơn kích thước ngăn xếp mà bạn có thể lấy nó từ "ulimit -s".

1

Không đặt một vật lớn như vậy lên chồng. Thay vào đó, hãy xem xét lưu trữ nó trong heap, bằng cách phân bổ với malloc() hoặc bạn bè của nó.

2.6M nổi không phải là nhiều và thậm chí trên hệ thống 32 bit, bạn cũng nên sử dụng không gian địa chỉ.

Nếu bạn cần phân bổ một mảng rất lớn, hãy đảm bảo sử dụng hệ thống 64 bit (giả sử bạn có đủ bộ nhớ!). Các hệ thống 32 bit chỉ có thể xử lý khoảng 3G cho mỗi quá trình, và thậm chí sau đó bạn không thể phân bổ tất cả nó như là một khối liên tiếp duy nhất.

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