✨Lỗi tràn ngăn xếp

Lỗi tràn ngăn xếp

Trong lập trình, lỗi tràn ngăn xếp xảy ra nếu các con trỏ ngăn xếp vượt quá giới hạn của ngăn xếp. Ngăn xếp có thể bao gồm một lượng hữu hạn các địa chỉ không gian, thường được xác định điểm bắt đầu của chương trình. Kích thước của ngăn xếp phụ thuộc vào nhiều yếu tố, bao gồm cả các chương trình, ngôn ngữ lập trình, kiến trúc, đơn/đa luồng, và lượng bộ nhớ có sẵn. Khi một chương trình cố gắng sử dụng nhiều không gian bộ nhớ hơn lượng bộ nhớ có sẵn trong ngăn xếp (nói cách khác, khi chương trình cố gắng truy cập vùng bộ nhớ ngoài giới hạn ngăn xếp, mà bản chất là lỗi tràn bộ nhớ đệm), ngăn xếp sẽ được coi là tràn và_ _thường dẫn đến chương trình lỗi hoặc chạy sai.

Phép đệ quy vô hạn

Nguyên nhân phổ biến nhất của lỗi tràn ngăn xếp là đệ quy quá sâu hoặc đệ quy vô hạn, trong đó có một hàm tự gọi mình quá nhiều lần làm không gian cần thiết để lưu trữ các biến và thông tin liên kết với mỗi lần gọi nhiều hơn kích thước ngăn xếp hiện có.

Một ví dụ về đệ quy vô hạn trong C.

int foo() { return foo(); }

Hàm foo, khi được gọi, nó tiếp tục gọi tự phân bổ thêm không gian trên ngăn xếp, cho đến khi ngăn xếp tràn, gây ra lỗi segmentation fault. Tuy nhiên, một số trình dịch thực hiện đệ quy đuôi, cho phép đệ quy vô hạn mà không bị tràn ngăn xếp. Bởi vì gọi đệ quy đuôi sẽ không mất thêm không gian của ngăn xếp.

Các trình biên dịch C sẽ có hiệu quả khi gọi đệ quy đuôi; Khi biên dịch chương trình đơn trên sử dụng gcc với đối số -O1 sẽ dẫn đến lỗi segmentation fault, nhưng lại không gây ra lỗi khi sử dụng đối số -O2 hoặc -O3, vì những chúng chỉ đến đối số -foptimize-sibling-calls trong tùy chọn trình biên dịch. Các ngôn ngữ khác, chẳng hạn như Scheme, yêu cầu tất cả các chỉ định để gọi đệ quy đuôi như là một phần của tiêu chuẩn ngôn ngữ.

Lỗi đệ quy quá sâu

Một hàm đệ quy hữu hạn theo lý thuyết nhưng gây ra lỗi tràn bộ đệm ngăn xếp trong thực tế có thể được sửa bằng cách chuyển đổi đệ quy thành một vòng lặp và lưu trữ các đối số chức năng trong một ngăn xếp. Điều này luôn luôn có thể, bởi vì lớp các hàm đệ quy ban đầu tương đương với lớp các hàm tính toán LOOP. Hãy xem xét ví dụ này trong mã giả như-C++ sau: void function (argument) { if (condition) { function (argument.next); } }

Khử đệ quy bằng cách tạo một vòng lặp: stack.push(argument); while (!stack.empty()) { argument = stack.pop(); if (condition) stack.push(argument.next); }

Ngăn xếp quá lớn

Một nguyên nhân khác gây ra tràn ngăn xếp là cấp phát bộ nhớ quá nhiều cho ngăn xếp, ví dụ như việc tạo các biến mảng cục bộ quá lớn. Vì lý do này, một số tác giả khuyên các mảng lớn hơn một vài kilobyt nên được cấp phát bộ nhớ động thay vì như là một biến cục bộ. 

Đây là một ví dụ của biến ngăn xếp quá lớn trong C: int foo() { double x[1048576]; }

Trong đoạn mã này, mảng x đã sử dụng 8 mebibytes dữ liệu (giả thiết mỗi biến _double_ là 8 bytes). Nếu lượng bộ nhớ này nhiều bộ nhớ hơn bộ nhớ có sẵn trong ngăn xếp (được thiết lập bởi số luồng xử lí hoặc do giới hạn hệ điều hành) thì sẽ xảy ra lỗi tràn ngăn xếp.

Lỗi tràn ngăn xếp sẽ trở nên tồi tệ hơn bởi bất cứ điều gì làm giảm kích thước ngăn xếp một cách hiệu quả của một chương trình nhất định. Ví dụ, cùng một chương trình đang chạy mà không sử dụng kiến trúc đa luồng có thể hoạt động tốt, nhưng khi được kích hoạt kiến trúc đa luồng, chương trình sẽ "sập". Điều này là bởi vì hầu hết các chương trình đa luồng có ít không gian ngăn xếp cho mỗi luồng hơn một chương trình không có hỗ trợ đa luồng. Bởi vì nhân hệ điều hành nói chung là dựa trên kiến trúc đa luồng nên những nhà phát triển nhân hệ điều hành thường không khuyến khích sử dụng các thuật toán đệ quy hoặc có bộ đệm ngăn xếp lớn. 

👁️ 0 | 🔗 | 💖 | ✨ | 🌍 | ⌚
Trong lập trình, **lỗi tràn ngăn xếp** xảy ra nếu các con trỏ ngăn xếp vượt quá giới hạn của ngăn xếp. Ngăn xếp có thể bao gồm một lượng hữu hạn các địa chỉ
Trong phần mềm, **tràn bộ đệm ở ngăn xếp** (tiếng Anh: _stack buffer overflow_ hay _stack buffer overrun_) xảy ra khi một chương trình viết địa chỉ bộ nhớ lên vùng gọi ngăn xếp của
Trong các lĩnh vực an ninh máy tính và lập trình, một **lỗi tràn bộ nhớ đệm** hay gọi tắt là **lỗi tràn bộ đệm** (tiếng Anh: _buffer overflow_) là một lỗi lập trình có
**Trận Yarmouk** (, còn được viết là _Yarmuk_, _Yarmuq_, hay trong tiếng Hy Lạp là _Hieromyax_, Ἱερομύαξ, hoặc _Iermouchas_, Ιερμουχάς) là một trận đánh lớn giữa quân đội Hồi giáo Rashidun với quân đội của
**Trần Khánh Dư** (chữ Hán: 陳慶餘, 13 tháng 3, 1240 - 23 tháng 4, 1340), hiệu là **Nhân Huệ vương** (仁惠王), là một chính khách, nhà quân sự Đại Việt dưới thời đại nhà Trần.
phải|Quân [[Liên bang miền Bắc Hoa Kỳ|Liên bang miền Bắc xung phong]]Trong 4 năm của cuộc Nội chiến Hoa Kỳ quân Liên bang miền Bắc và quân Liên minh miền Nam đánh nhau trong nhiều
nhỏ|Động cơ phản lực của [[VA-111 Shkval, đây là loại động cơ phản lực luồng có lượng thông qua lớn từ nước hút vào]] nhỏ|[[VA-111 Shkval Nga, đầu tạo siêu bọt.]] [[Tàu ngầm hạt nhân
**Hệ thống bảng xếp hạng FIFA** là phương pháp tính toán được dùng trước đây bởi FIFA dành cho các đội tuyển quốc gia trong môn bóng đá. Hệ thống này được FIFA công bố
Mùa đầu tiên của chương trình **_Anh trai vượt ngàn chông gai_** được phát sóng trên kênh truyền hình VTV3 từ ngày 29 tháng 6 đến ngày 19 tháng 10 năm 2024. Sau chương trình,
**Trận tấn công Trân Châu Cảng** (hay **Chiến dịch Hawaii** và **Chiến dịch AI** của Hawaii, và **Chiến dịch Z** theo cách gọi của Bộ Tổng tư lệnh Đế quốc Nhật Bản) là một cuộc
**Trận Crete** (; ) là một trận đánh diễn ra tại đảo Crete của Hy Lạp giữa quân đội Đức Quốc xã và quân đội Đồng Minh trong Chiến tranh thế giới thứ hai, bắt
**Hải chiến mũi Esperance** hay theo Nhật Bản gọi là **Savo-tō Oki Kaisen** (サボ島沖海戦, サボとうおきかいせん) diễn ra từ ngày 11 đến ngày 12 tháng 10 năm 1942, là một trong nhiều trận hải chiến giữa
**Trận Agincourt** (; ) là một trận đánh tiêu biểu trong chiến tranh Trăm Năm giữa Anh với Pháp. Trận đánh diễn ra ngày 25 tháng 10 năm 1415 (Ngày Thánh Crispin) gần Azincourt, ở
**Nhà Trần** (chữ Nôm: 茹陳, chữ Hán: 陳朝, Hán Việt: _Trần triều_) là một triều đại quân chủ cai trị nước Đại Việt từ năm 1226 đến năm 1400. Đây là triều đại được lưu
**Trận Đồng Quan** hay **Chiến dịch Đồng Quan** (chữ Hán: 潼關之戰 _Đồng Quan chi chiến_) là trận đánh chiến lược diễn ra giữa quân đội triều đình trung ương nhà Đông Hán do thừa tướng
**Trận Waterloo** (phiên âm tiếng Việt: **Oa-téc-lô**) là trận chiến diễn ra vào ngày Chủ nhật 18 tháng 6 năm 1815, gần Waterloo, thuộc Bỉ. Quân Pháp dưới sự chỉ huy của Hoàng đế Napoleon
Lối chơi của dòng game Pokémon chính liên quan đến việc thu phục và huấn luyện những sinh vật hư cấu được gọi là "Pokémon" và cho chúng chiến đấu với Pokémon của các trainer
**Ngân hàng thương mại cổ phần Á Châu** (tên giao dịch bằng tiếng Anh: _Asia Commercial Joint Stock Bank_), được gọi tắt là **Ngân hàng Á Châu (ACB)**, chính thức đi vào hoạt động kinh
**Trận Rotterdam** là một trận đánh thuộc chiến tranh thế giới thứ hai diễn ra từ ngày 10 đến 14 tháng 5 năm 1940, là một phần trong cuộc xâm chiếm Hà Lan của Đức.
**Trận Poltava** (, ), còn gọi là **Trận đánh Pultowa**, là trận đánh lớn diễn ra vào ngày 27 tháng 6 năm 1709 theo lịch Julius giữa hai đoàn quân hùng hậu: Quân đội Nga
**Trận Jutland** là trận hải chiến lớn nhất trong Chiến tranh Thế giới thứ nhất diễn ra giữa Hạm đội công hải của Đức và Đại hạm đội của Anh từ ngày 31 tháng 5
**Trận Austerlitz** (còn gọi là **Trận Ba Hoàng đế** hay **Trận Tam Hoàng**), là một trong những trận đánh quan trọng và có tính chất quyết định trong chiến tranh Napoléon. Trận đánh xảy ra
**Mặt trận giải phóng động vật** (tiếng Anh: **Animal Liberation Front**) viết tắt là **ALF**, là một nhóm hoạt động quốc tế không người lãnh đạo của phong trào giải phóng động vật, tham gia
**Mặt trận Dân tộc Giải phóng miền Nam Việt Nam** (phía Hoa Kỳ, Việt Nam Cộng hòa và các đồng minh thường gọi là **Việt Cộng**) là một tổ chức liên minh chính trị hoạt
**Trần Văn Thủy** (sinh ngày 26 tháng 11 năm 1940) là một đạo diễn phim tài liệu người Việt Nam, nổi tiếng qua các tác phẩm _Hà Nội trong mắt ai_, _Chuyện tử tế_ và
**Bảng xếp hạng bóng đá nam FIFA** (_FIFA Men's World Ranking_) là hệ thống xếp hạng dành cho các đội tuyển quốc gia nam ở môn bóng đá, dẫn đầu là Argentina tính đến tháng
**Trận Hà Lan** () là một phần trong "Kế hoạch Vàng" () - cuộc xâm lăng của Đức Quốc xã vào Vùng đất thấp (Bỉ, Luxembourg, Hà Lan) và Pháp trong chiến tranh thế giới
**Trận Vukovar** là một cuộc vây hãm kéo dài 87 ngày từ tháng 8 đến tháng 11 năm 1991 ở thành phố Vukovar, miền đông Croatia, áp đặt bởi Quân đội nhân dân Nam Tư
**Ngân hàng TMCP Đầu tư và Phát triển Việt Nam** (tên giao dịch Tiếng Anh: _Joint Stock Commercial Bank for Investment and Development of Vietnam_ ) tên gọi tắt: "**BIDV",** là ngân hàng thương mại
**Trận Kiev năm 1941** là trận công kích lớn thứ ba của Đức Quốc Xã vào mặt trận Tây Nam của Hồng quân Liên Xô (ngả qua Urkraina) trong Chiến dịch Barbarossa, sau Trận Dubno
**Trận Mars-la-Tour**, còn được gọi là **Trận Vionville**, **Trận Vionville–Mars-la-Tour** hay **trận Rezonville** theo tên các ngôi làng nằm trên đường Metz-Verdun Sau những thất bại mở màn của quân đội Pháp đầu tháng 8
**Trận Hastings** là một trận đánh diễn ra vào ngày 14 tháng 10 năm 1066 giữa lực lượng Norman /nɔːmən/ dưới sự lãnh đạo của Công tước William II xứ Normandy và quân đội Anglo-Saxon
**Trận Königgrätz**, còn gọi là **Trận Sadowa** hay **Trận Sadová** theo tiếng Tiệp Khắc, là trận đánh then chốt của cuộc Chiến tranh Áo-Phổ, diễn ra vào ngày 3 tháng 7 năm 1866, và chấm
**Trận Tốt Động – Chúc Động** hay **Trận Tụy Động** là một trận đánh diễn ra từ ngày 5 đến ngày 7 tháng 11 năm 1426 giữa nghĩa quân Lam Sơn và quân đội nhà
**Trận Dunkerque** (hay **Trận Dunkirk**) là một trận đánh quan trọng nổi tiếng trong Chiến tranh thế giới thứ hai, diễn ra tại xã Dunkerque, Pháp từ ngày 26 tháng 5 cho đến ngày 4
**Trận Höchstädt** hay còn được gọi là **trận Blindheim** hoặc là **trận Blenheim** theo cách gọi của người Anh, diễn ra vào ngày 13 tháng 8 năm 1704, là một trận đánh lớn trong cuộc
**Trận Manzikert** là một trận đánh diễn ra vào ngày 26 tháng 8 năm 1071 ở gần Manzikert (Malazgirt, tỉnh Muş, Thổ Nhĩ Kỳ ngày nay) giữa đế quốc Byzantium (Đông La Mã) và đế
**Trận Marathon** (tiếng Hy Lạp: Μάχη τοῡ Μαραθῶνος Mache tou Marathonos là trận đánh nổi tiếng diễn ra vào mùa thu năm 490 TCN trong Cuộc xâm lược Hy Lạp lần thứ nhất của Ba
**Trận kinh thành Huế năm 1885** là một sự kiện chính trị, một trận tập kích của quân triều đình nhà Nguyễn do Tôn Thất Thuyết chỉ huy đánh vào lực lượng Pháp. Sự kiện
**Trận Hải Phòng** là trận đánh diễn ra từ ngày 20 tháng 11 đến 26 tháng 11 năm 1946 và từ ngày 20 tháng 12 năm 1946 đến 25 tháng 4 năm 1947 ở khu
**Trận bán đảo Kerch (1942)** là tổ hợp ba chiến dịch quân sự lớn của Hồng Quân Liên Xô chống lại quân đội Đức Quốc xã và quân chư hầu România tại bán đảo Kerch
thumb|Bên trong một cửa hàng tiện lợi [[7-Eleven của Nhật Bản]] thumb|Một cửa hàng [[Bodega (store)|bodega tiêu biểu tại New York City]] **Cửa hàng tiện lợi** hay **Cửa hàng tiện ích** là một cửa hàng
**Trận Thành cổ Quảng Trị** () là một trận chiến giữa Quân Giải phóng miền Nam Việt Nam được sự hỗ trợ về hậu cần của Quân đội nhân dân Việt Nam với Quân đội
**Trận Ia Đrăng** là một trong những trận lớn đầu tiên giữa liên quân Quân lực Việt Nam Cộng hòa-Quân đội Hoa Kỳ và Quân Giải phóng miền Nam Việt Nam trong thời kỳ Chiến
**Trận Carrhae** xảy ra gần thị trấn Carrhae năm 53 TCN, là một chiến thắng quyết định cho Spahbod (tướng) Surena của người Parthava trước quân xâm lược La Mã dưới sự chỉ huy của
**Trận Đan Mạch** là tên gọi cuộc tấn công của quân đội Đức Quốc xã băng qua biên giới Đan Mạch ngày 9 tháng 4 năm 1940 trên cả ba mặt trận đất liền, biển
**Trận Tours** (ngày 10 tháng 10 năm 732), còn được gọi là **trận Poitiers** (phát âm tiếng Việt: **Poachiê**), tiếng - _ma‘arakat Balâṭ ash-Shuhadâ_) là một trận chiến diễn ra ở một địa điểm giữa
**Mặt trận Srem** (, ) là tuyến phòng thủ vững chắc của Wehrmacht và Quân lực Croatia nằm tại Srem và Đông Slavonia trong Thế chiến thứ hai từ 23 tháng 10 năm 1944 đến
**Trận Appomattox Court House**, xảy ra vào sáng ngày 9 tháng 4 năm 1865, là trận giao tranh cuối cùng của Binh đoàn Bắc Virginia dưới quyền chỉ huy của đại tướng Liên minh miền
**Trận Hồng Kông** (8-25 tháng 12 năm 1941), được biết đến với tên gọi là **Phòng thủ Hồng Kông** hay **Hồng Kông thất thủ** là một trong những trận đánh đầu tiên của Chiến tranh