2012-05-10 23 views
6

Tôi đang sử dụng VS 2010.
Khi tôi chạy chương trình này trong chế độ Debug nó ném stack overflow ngoại lệ và cho thấy một breakline trong file chkstk.asm tại dòng 99.
Nhưng khi tôi chạy nó trong chế độ Release thì OK.
Ngoài ra nếu tôi giảm kích thước của một trong các mảng thành 10000 thì nó hoạt động tốt trong Gỡ lỗi. Lý do là gì?stack overflow ngoại lệ trong chương trình ngớ ngẩn

#include <iostream> 

using namespace std; 
int main() 
{ 
    char w[1000001], temp[1000001]; 
    cout<<"Why?"<<endl; 
    return 0; 
} 
+3

Bạn đã bật tối ưu hóa nào trong chế độ phát hành? Có một cơ hội tốt mà trình biên dịch chỉ là loại bỏ các mảng. –

+0

có thể trùng lặp của [Ngăn xếp ngăn xếp khi gỡ lỗi nhưng không được phát hành] (http://stackoverflow.com/questions/5670904/stack-overflow-when-debugging-but-not-in-release) –

+0

Bạn có hỏi "Cái gì là lý do tràn? " Hoặc "Lý do hành vi thay đổi trong các chế độ xây dựng khác nhau là gì?" Hay cái gì khác? –

Trả lời

11

Bởi vì ngăn xếp là khá nhỏ, khoảng 1MB trên hầu hết các hệ thống, bạn đang tràn nó với bộ đệm lớn của bạn. Để khắc phục điều đó, chỉ cần phân bổ trên heap như sau:

#include <iostream> 

using namespace std; 
int main() 
{ 
    char* w = new char[1000001]; 
    char* temp = new char[1000001]; 
    cout<<"Why?"<<endl; 
    delete[] w; 
    delete[] temp; 
    return 0; 
} 
+2

hoặc sử dụng 'std :: vector' như một người khác đã được đề xuất! –

5

Ngăn xếp khá nhỏ (~ 1MB). Bạn đang làm đầy nó với số lượng lớn các phần tử trong các mảng đó.

Nếu bạn cần thêm dung lượng, hãy thử phân bổ trên heap (mà con trỏ làm).

Cách tốt nhất để thực hiện điều này là với vectơ, mà trong nội bộ lưu trữ những thứ trên đống:

std::vector<char> w (1000001); 
std::vector<char> temp (1000001); 
4

Mảng trong việc lưu trữ tự động được cấp phát trên stack. Không gian ngăn xếp bị giới hạn. Khi không gian trên ngăn xếp không đủ để phân bổ các biến tự động, ngoại lệ tràn ngăn xếp xảy ra.

Nếu bạn cần mảng lớn, hãy sử dụng phân bổ tĩnh hoặc động thay thế.

Để phân bổ tĩnh, hãy di chuyển các khai báo sang bên ngoài main().

Đối với phân bổ năng động, sử dụng mã dưới đây:

char *w = new char[1000001], *temp = new char[1000001]; 
// Work with w and temp as usual, then 
delete[] w; 
delete[] temp; 

Cuối cùng, hãy xem xét sử dụng các container tiêu chuẩn thay vì mảng đồng bằng: std::array là một mảng tốt hơn nếu bạn không cần phải thay đổi kích thước (nó được cấp phát trên stack, và sẽ không giải quyết được vấn đề này); std::string cũng là một ứng cử viên tốt để thay thế các mảng char.

+2

Tôi không nghĩ rằng 'std :: array' sẽ giải quyết vấn đề của mình. Nó sẽ * vẫn * phân bổ dữ liệu trên ngăn xếp. Hãy thử 'std :: vector'. –

+0

@ Robᵩ Bạn nói đúng, nó sẽ không! Tôi đã đề cập đến 'std :: array' như là một thay thế cho mảng đồng bằng, không phải là một cách để giải quyết vấn đề cụ thể này. Tôi có thể thấy phần này của câu trả lời có thể gây hiểu lầm như thế nào, vì vậy tôi đã chỉnh sửa nó để làm rõ. Cảm ơn! – dasblinkenlight

5

Bạn đang phân bổ quá nhiều nội dung trên ngăn xếp; có lẽ trong chế độ gỡ lỗi, ngăn xếp bị chiếm đóng nhiều hơn vì các kiểm tra an toàn khác nhau, hoặc được cố ý nhỏ hơn để giúp bạn phát hiện các vấn đề như vậy trước đó. Nhưng dù sao, làm cho mảng lớn hơn một chút sẽ kích hoạt một tràn ngăn xếp ngay cả trong chế độ phát hành (trừ khi trình biên dịch tối ưu hóa chúng ra hoàn toàn).

Gốc của vấn đề ở đây là bạn không nên cấp phát các nội dung lớn trên ngăn xếp, có kích thước khá giới hạn (1 MB theo mặc định trên Windows với VC++) và chỉ được sử dụng cho các bộ đệm/đối tượng nhỏ. Nếu bạn cần phân bổ lớn, hãy thực hiện chúng trên heap (với new/malloc), tốt nhất là sử dụng con trỏ thông minh để tránh rò rỉ bộ nhớ.

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