[英]Segmentation Fault in the implementation of a sorting function
我正在嘗試基於為我的編程課程提供的偽代碼實現排序算法,我和我的合作伙伴一直在收到(核心轉儲)錯誤,通常特別是分段錯誤。 我知道這通常意味着程序試圖訪問它不允許的內存,但我不確定如何解決這個問題。
#include <iostream>
#include <cmath>
using namespace std;
void FlipFlopSort(int *Array, int begin, int end){
int length = (end-begin);
float midh = 2*(float)length/3;
midh = ceil(midh);
float midl = (float)length/3;
midl = ceil(midl);
//cout << "size of sorted area = " << length << endl;
if(length<=2){
//cout << "Length = 2" << endl;
if(Array[begin] > Array[begin+1]){
swap(Array[begin], Array[begin+1]);
}
}else{
//cout << "Recursion Begin 1" << endl;
FlipFlopSort(Array, begin, midh);
//cout << "Recursion End" << endl;
FlipFlopSort(Array, midl, end);
//cout << "Recursion Begin 2" << endl;
FlipFlopSort(Array, begin, midh);
}
}
int main(){
// Declare Variables and Read Inputs
int n;
cin >> n;
int Array[n];
for(int i = 0; i < n; i++){
cin >> Array[i];
}
FlipFlopSort(Array, 0, n);
for(int i = 0; i<n; i++){
if(i != (n-1)){
cout << Array[i] << " ";
}else{
cout << Array[i] << endl;
}
}
return 0;
}
讓我們開始:
int n;
cin >> n;
int Array[n];
int* Array = new int[n];
您可能會遇到分段錯誤的原因之一是由於以下行:
if (length <= 2) {
//cout << "Length = 2" << endl;
if (Array[begin] > Array[begin + 1]) {
swap(Array[begin], Array[begin + 1]);
}
}
void FlipFlopSort(int *Array, int begin, int end){
int length = (end-begin);
if (length <= 1) {
return;
}
...
}
另一個原因是因為您計算的是中間尺寸而不是索引,這意味着您不會向它們添加開始。
考慮:開始=100,結束=103。 -> 長度 = 3,midl = 1 和 midh = 2。有意義嗎? 不! 在這種情況下,這些不是有效的索引。 你應該寫
midh += begin;
midl += begin;
經過他們的計算。
最后一件事,你應該避免使用浮點數(除非你真的需要)所以我會寫:
const int midl = begin + length / 3;
const int midh = begin + 2 * midl;
它與您編寫的內容不同,但它仍然有效,而您的則有風險(上限值很可疑,因為您可能會發現自己位於數組的末尾)。
void FlipFlopSort(int* Array, int begin, int end) {
const int length = end - begin;
if (length <= 1) {
return;
}
const int midh = begin + 2 * length / 3;
const int midl = begin + length / 3;
//cout << "size of sorted area = " << length << endl;
if (length <= 2) {
//cout << "Length = 2" << endl;
if (Array[begin] > Array[begin + 1]) {
swap(Array[begin], Array[begin + 1]);
}
}
else {
FlipFlopSort(Array, begin, midh);
FlipFlopSort(Array, midl, end);
FlipFlopSort(Array, begin, midh);
}
}
當您swap
,您必須確保length
至少為 2,否則您將交換數字越界。 您的midl
和midh
值目前是錯誤的。 它們與begin
,因此您需要向它們添加begin
。 但是,您可以將midl
添加到Array
本身並跳過函數中的begin
參數以簡化界面。
我還將用整數版本替換浮點std::ceil
操作。
// A function to do integer division and return the ceil value
size_t DivCeil(size_t dividend, size_t divisor) {
return 1U + ((dividend - 1U) / divisor);
}
void FlipFlopSort(int* Array, size_t length) {
if(length > 2) {
// calculate midl & midh
size_t midl = DivCeil(length, 3U);
size_t midh = DivCeil(2U * length, 3U);
FlipFlopSort(Array, midh);
// add midl to Array and sub midl from length
FlipFlopSort(Array + midl, length - midl);
FlipFlopSort(Array, midh);
} else if(length == 2) {
if(Array[1] < Array[0]) {
// swap the values
std::swap(Array[0], Array[1]);
}
} // else length < 2 ... don't do anything
}
#include <iostream>
#include <vector>
int main() {
size_t n;
if(std::cin >> n) { // check that the user entered a number
// don't use VLA:s, use a std::vector instead
std::vector<int> Array(n);
for(size_t i = 0; i < Array.size(); ++i) {
std::cin >> Array[i];
}
FlipFlopSort(Array.data(), Array.size());
for(int value : Array) {
std::cout << value << '\n';
}
}
}
如果您希望排序算法更通用且可用於標准容器,您可以用迭代器替換輸入參數。
例子:
#include <algorithm> // std::iter_swap
#include <iterator> // std::distance, std::next
// A function to do integer division and return the ceil value
template<typename T>
T DivCeil(T dividend, T divisor) {
return 1 + ((dividend - 1) / divisor);
}
template<typename It>
void FlipFlopSort(It begin, It end) {
auto length = std::distance(begin, end); // iterator version of "length = end-begin"
static constexpr decltype(length) two = 2; // constant of the same type as length
static constexpr decltype(length) three = 3; // -"-
if(length > two) {
// calculate midl & midh iterators
auto midl = std::next(begin, DivCeil(length, three));
auto midh = std::next(begin, DivCeil(two * length, three));
FlipFlopSort(begin, midh);
FlipFlopSort(midl, end);
FlipFlopSort(begin, midh);
} else if(length == two) {
if(*std::next(begin) < *begin) {
// swap the values pointed at by the iterators
std::iter_swap(begin, std::next(begin));
}
} // else length == 1 or 0 ... don't do anything
}
用法:
#include <iostream>
#include <vector>
int main() {
size_t n;
if(std::cin >> n) {
std::vector<int> Array(n);
for(size_t i = 0; i < Array.size(); ++i) {
std::cin >> Array[i];
}
FlipFlopSort(std::begin(Array), std::end(Array));
for(int value : Array) {
std::cout << value << '\n';
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.