2009-02-21 24 views
28

Các mã sau đây được tạo ra một lỗi tràn stack cho tôiBắt một tràn ngoại lệ stack khi khai báo một mảng lớn

int main(int argc, char* argv[]) 
{ 
    int sieve[2000000]; 
    return 0; 
} 

Làm thế nào để làm được việc này? Tôi đang sử dụng Turbo C++ nhưng muốn giữ mã của tôi ở C

EDIT:

Cảm ơn lời khuyên. Đoạn mã trên chỉ là ví dụ, tôi thực sự khai báo mảng trong một hàm và không phải trong phần chính. Ngoài ra, tôi cần các mảng được khởi tạo để số không, vì vậy khi tôi googled malloc, tôi phát hiện ra rằng calloc là hoàn hảo cho mục đích của tôi.

Malloc/calloc cũng có lợi thế hơn phân bổ trên ngăn xếp cho phép tôi khai báo kích thước bằng biến.

+1

vẫn cười khúc khích @ "sàng" – el2iot2

+6

Tôi đọc "ngoại lệ tràn ngăn xếp" và tự nghĩ "...? Có vấn đề gì với trang web?" Rõ ràng tôi dành quá nhiều thời gian ở đây: -/ –

+1

Tôi khá chắc rằng kiểu câu hỏi này phải xuất hiện trước đây trên trang này, nhưng tìm kiếm "tràn ngăn xếp" không sử dụng bất cứ thứ gì –

Trả lời

46

mảng của bạn là cách quá lớn để phù hợp với chồng, xem xét sử dụng đống:

int *sieve = malloc(2000000 * sizeof(*sieve)); 

Nếu bạn thực sự muốn thay đổi kích thước ngăn xếp, take a look at this document.

Mẹo: - Don' đừng quên giải phóng bộ nhớ được cấp phát động của bạn khi nó không còn cần thiết nữa.

+16

Vì đây là C, bạn không cần (và trên thực tế, không nên) bỏ giá trị trả về của malloc. – aib

+1

Tại sao bạn không cast kết quả của malloc? Bạn sẽ không phải bỏ nó từ void * để làm được gì nhiều với nó? – Amy

+4

@ yodaj007: Bạn không cần phải truyền một cách rõ ràng. Vì biến được chỉ định cũng là một kiểu con trỏ, phép gán thực hiện một chuyển đổi ngầm định. – jweyrich

2

Bạn nên ngừng phân bổ nó trên heap chứ không phải ngăn xếp. một cái gì đó như

int main(int argc, char* argv[]) 
{ 
    int * sieve; 
    sieve = malloc(20000); 
    return 0; 
} 
+7

bạn quên miễn phí (sàng) –

+1

Và kiểm tra sàng cho NULL – paulm

+0

" Tôi chỉ sàng cho bạn "- -Các Zohan – DragonLord

1

Đó là khoảng 7MB không gian ngăn xếp. Trong studio trực quan, bạn sẽ sử dụng/STACK: ###, ### để phản ánh kích thước bạn muốn. Nếu bạn thực sự muốn một chồng lớn (có thể là một lý do chính đáng, sử dụng LISP hoặc một cái gì đó :), ngay cả đống được giới hạn trong phân bổ nhỏ của trước khi buộc bạn sử dụng VirtualAlloc), bạn cũng có thể muốn đặt PE của bạn để xây dựng với/LARGEADDRESSAAWARE (Trình liên kết của Visual Studio một lần nữa), nhưng cấu hình của tiêu đề PE của bạn để cho phép nhị phân biên dịch của bạn địa chỉ đầy đủ 4GB không gian địa chỉ 32'bit (nếu chạy trong WOW64). Nếu xây dựng các tệp nhị phân thực sự lớn, bạn cũng thường sẽ cần phải cấu hình/bigobj làm một trình liên kết tham chiếu bổ sung. Và nếu bạn vẫn cần thêm không gian, bạn có thể vi phạm triệt để quy ước bằng cách sử dụng một cái gì đó tương tự (liên kết của MSVC)/merge :, sẽ cho phép bạn đóng một phần vào một phần khác, vì vậy bạn có thể sử dụng từng byte đơn lẻ cho một phần mã/dữ liệu được chia sẻ duy nhất. Đương nhiên bạn cũng sẽ cần phải cấu hình quyền SECTIONS trong một tập tin def hoặc với #pgrama.

11

Có 3 cách:

  1. Phân bổ mảng trên đống - sử dụng malloc(), như áp phích khác đề nghị. Đừng quên free() nó (mặc dù cho main() nó không phải là quan trọng - Hệ điều hành sẽ làm sạch bộ nhớ cho bạn khi chấm dứt chương trình).
  2. Khai báo mảng trên cấp đơn vị - nó sẽ được phân bổ trong phân đoạn dữ liệu và hiển thị cho mọi người (thêm static vào khai báo sẽ giới hạn mức hiển thị cho đơn vị).
  3. Khai báo mảng của bạn là static - trong trường hợp này, nó sẽ được phân bổ trong phân đoạn dữ liệu, nhưng chỉ hiển thị trong main().
+1

Tôi chỉ làm cho nó tĩnh: 'main()' chỉ nên được gọi một lần, vì vậy không có cạm bẫy; không cần 'malloc()' ở đây ... – Christoph

0

Có một số lý do tại sao bạn không thể sử dụng alloca() để phân bổ không gian bạn cần trên khung ngăn xếp dựa trên mức độ lớn của đối tượng thực sự cần phải không?

Nếu bạn làm điều đó, và vẫn phá vỡ ngăn xếp, hãy đặt nó trong phân bổ đống. Tôi khuyên bạn KHÔNG nên khai báo nó là static trong main() và đặt nó vào trong phân đoạn dữ liệu.

Nếu nó thực sự phải lớn và chương trình của bạn không thể cấp phát trên heap, chương trình của bạn thực sự không có doanh nghiệp đang chạy trên loại máy đó để bắt đầu.

Bạn đang cố hoàn thành những gì (chính xác)?

+0

Tôi đang sử dụng các vấn đề từ ProjectEuler.net để tìm hiểu C, và đang triển khai thuật toán Sieve of Eratosthenes, vì vậy nó không phải là lớn. malloc hoạt động tốt cho mục đích của tôi mặc dù –

1

Sử dụng malloc. Tất cả kiểm tra kiểu trả về không phải là null, nếu nó là null thì hệ thống của bạn đơn giản không có đủ bộ nhớ để phù hợp với nhiều giá trị đó.

-1

Thay vào đó hãy sử dụng malloc. Cú pháp:

newnode=(struct node *)malloc(sizeof(struct node)) 
0

Mảng của bạn rất lớn.

Có thể máy hoặc hệ điều hành của bạn không có hoặc muốn phân bổ quá nhiều bộ nhớ.


Nếu bạn hoàn toàn cần một mảng rất lớn, bạn có thể thử để phân bổ nó tự động (sử dụng malloc(...)), nhưng sau đó bạn có nguy cơ bị rò rỉ bộ nhớ. Đừng quên giải phóng bộ nhớ.

Lợi thế của malloc là nó cố gắng phân bổ bộ nhớ trên heap thay vì ngăn xếp (do đó bạn sẽ không bị tràn ngăn xếp).

Bạn có thể kiểm tra giá trị mà malloc trả về để xem liệu phân bổ đã thành công hay thất bại. Nếu nó không thành công, chỉ cần cố gắng malloc một mảng nhỏ hơn.


Một tùy chọn khác là sử dụng cấu trúc dữ liệu khác có thể thay đổi kích cỡ khi đang bay (như danh sách được liên kết). Wether tùy chọn này là tốt phụ thuộc vào những gì bạn sẽ làm gì với dữ liệu.

Một tùy chọn khác là lưu trữ mọi thứ trong một tệp, phát trực tuyến dữ liệu. Cách tiếp cận này là chậm nhất.

Nếu bạn đi cho lưu trữ trên ổ đĩa cứng, bạn cũng có thể sử dụng một thư viện hiện có (đối với cơ sở dữ liệu)

0

Như Turbo C/C++ là trình biên dịch 16 bit int datatype tiêu thụ khoảng 2 byte. 2bytes * 2000000 = 40,00,000 bytes = 3,8147MB dung lượng.

Biến tự động của hàm được lưu trữ trong ngăn xếp và nó gây ra tràn bộ nhớ ngăn xếp. Thay vào đó hãy sử dụng bộ nhớ dữ liệu [sử dụng biến tĩnh hoặc toàn cục] hoặc bộ nhớ heap động [sử dụng malloc/calloc] để tạo bộ nhớ cần thiết theo sự sẵn có của ánh xạ bộ nhớ bộ xử lý.

-3

Mảng của bạn quá lớn hoặc lớn để máy phân bổ. Sử dụng MALLOC

+0

Chào mừng bạn đến với Stack Overflow! Bài đăng này đã có câu trả lời được chấp nhận, cũng như câu trả lời rất giống với câu trả lời của riêng bạn. Trong tương lai, hãy dành thời gian để đảm bảo rằng câu trả lời của bạn tăng thêm giá trị vượt quá những giá trị đã được cung cấp. Xem: [Cách trả lời] (https://stackoverflow.com/help/how-to-answer) – avojak

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