У мові програмування C++ використання умовних операторів є невід’ємною частиною розробки програмного забезпечення. Проте, іноді можуть виникати неочікувані проблеми, пов’язані з їх використанням. Однією з таких проблем є виникнення помилки SIGSEGV (segmentation fault), яка може виникнути через некоректне використання умовних операторів.
Розглянемо практичний приклад, щоб з’ясувати, чому виникає ця проблема та як її уникнути.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include "bits/stdc++.h" using namespace std; vector<int> findMedian(vector<int> &arr, int n) { priority_queue<int> maxheap; // Store smaller elements (left half) priority_queue<int, vector<int>, greater<int>> minheap; // Store larger elements (right half) vector<int> medians; for (int i = 0; i < n; i++) { maxheap.push(arr[i]); // Ensure smaller elements are in the maxheap if (minheap.size() > 0 && maxheap.top() > minheap.top()) { minheap.push(maxheap.top()); maxheap.pop(); } // Maintain a balance between sizes of the two heaps if (minheap.size() > maxheap.size() + 1) { maxheap.push(minheap.top()); minheap.pop(); } else if (maxheap.size() > minheap.size() + 1) { minheap.push(maxheap.top()); maxheap.pop(); } // Calculate the median based on whether the total count of elements is even or odd if ((minheap.size() + maxheap.size()) % 2 == 0) { medians.push_back((minheap.top() + maxheap.top()) / 2); } else { // Implied 'else' here since the size difference can't be more than 1 if (maxheap.size() > minheap.size()) { medians.push_back(maxheap.top()); } else { // Must be minheap.size() > maxheap.size() medians.push_back(minheap.top()); } } } return medians; } |
Програмний код, наведений вище, призначений для знаходження медіани масиву чисел. Однак, якщо змінити наступні дві строки коду на:
1 |
if (maxHeap.size() - minHeap.size() > 1) |
та
1 |
else if (minHeap.size() - maxHeap.size() > 1) |
то код спричиняє помилку SIGSEGV під час виконання, навіть якщо ці дві строки коду математично еквівалентні. Чому це відбувається?
Помилка виникає через те, що при обчисленні виразів типу maxHeap.size() - minHeap.size()
можуть виникати випадки переповнення, особливо при використанні беззнакових типів даних. Це може призвести до непередбачуваної поведінки програми, включаючи помилку SIGSEGV.
Рекомендується замість цього використовувати більш безпечні способи порівняння розмірів куп. Наприклад, можна використовувати порівняння розмірів куп з врахуванням знака, або використовувати бібліотеки стандарту C++, які надають інструменти для роботи з контейнерами динамічного розміру, такі як std::vector
та std::deque
.