【发布时间】:2020-05-18 07:35:33
【问题描述】:
我正在努力实现几种不同的排序方法,由于某种原因,我的合并排序算法不适用于大型数据集。该排序将适用于 115,000 个单词,但在达到 135,000 个单词时停止工作。一旦我达到这个高度,我最终会遇到分段错误。我不明白段错误来自哪里。该排序对包含 5K 到 125K 字符串的文本文件有效。
readFile 数组被初始化为文本文件中的字数。调试时,传递给mergeSort() 函数的最后一个数字似乎如下:
#0 0x0000000000402a87 in merge (inputString=0x7fffffbde790, from=0, mid=67499, to=134999) at mergeSort.cpp:102
n1 = 67500
n2 = 67500
i = 0
j = 0
k = 32767
L = <error reading variable L (value requires 2160000 bytes, which is more than max-value-size)>
R = <error reading variable R (value requires 2160000 bytes, which is more than max-value-size)>
#1 0x0000000000402921 in mergeSort (inputString=0x7fffffbde790, from=0, to=134999) at mergeSort.cpp:88
mid = 67499
void mergeSort(string readFile[], int from, int to) {
if (from < to) {
int mid = from + (to - from) / 2;
mergeSort(readFile, from, mid);
mergeSort(readFile, mid + 1, to);
merge(readFile, from, mid, to);
}
}
void merge(string readFile[], int from, int mid, int to) {
int n1 = mid - from + 1;
int n2 = to - mid;
string L[n1];
string R[n2];
for (int i = 0; i < n1; i++) {
L[i] = readFile[from + i];
}
for (int i = 0; i < n2; i++) {
R[i] = readFile[mid + i + 1];
}
int i = 0;
int j = 0;
int k = from;
while (i < n1 && j < n2) {
if (L[i] <= R[j]) {
readFile[k] = L[i];
i++;
} else {
readFile[k] = R[j];
j++;
}
k++;
}
while (i < n1) {
readFile[k] = L[i];
i++;
k++;
}
while (j < n2) {
readFile[k] = R[j];
j++;
k++;
}
}
【问题讨论】:
-
递归例程可能导致分段错误(由于堆栈溢出)。阅读*.com/a/12146513/3656081 以获取可能的建议。如果此代码要投入生产,您可能希望重组程序以进行迭代。
-
替代方案是 Bottom_Up 迭代合并排序,请参阅Merge sort - Wikipedia。使用典型的递归合并排序,您将在 Linux 上达到 4M 默认堆栈限制,大约为 100,000
int。 -
您的问题缺少minimal reproducible example 和错误发生时的错误输出(最好是完整的回溯)。
-
@rcgldr 到最后 n1 和 n2 最终都是 67,500。这可能是一个愚蠢的问题,但我假设分配有 135,000 个元素的数组和分配有 67,500 个元素的两个数组在堆栈上的数量相同,对吗?
-
@rcgldr 我也更新了我的回溯。
标签: c++ segmentation-fault mergesort