【问题标题】:Getting Segmentation Fault with string Heap Sort code in C++在 C++ 中使用字符串堆排序代码获取分段错误
【发布时间】:2011-11-27 15:41:50
【问题描述】:
int heapSize = 20; //variable 
int left(int i) {
return (2 * i) + 1;
}

int right(int i) {
return (2 * i) + 2;
}

void heapify(string arr[], int i) {
int l = left(i);
int great=0;
int r = right(i);
if ( ((strcmp(arr[l].c_str(),arr[i].c_str()))>0) && (l < heapSize)) {
great = l;
}
else {
great = i;
}

if ( ((strcmp(arr[r].c_str(),arr[great].c_str()))>0) && (r < heapSize)) {
great = r;
}
if (great != i) {
string temp = arr[i];
arr[i] = arr[great];
arr[great] = temp;
heapify(arr, great); //Getting segment here 
}

}

void BuildMaxHeap(string arr[]) {
for (int i = (heapSize - 1) / 2; i >= 0; i--) {
heapify(arr, i);
}
}

void HeapSort(string arr[]) {
BuildMaxHeap(arr); //
for (int i = heapSize; i > 0; i--) {
string temp = arr[0];
arr[0] = arr[heapSize - 1];
arr[heapSize - 1] = temp;
heapSize = heapSize - 1;
heapify(arr, 0);
}

}

当 heapSize 大于 15(例如 20 个元素)时,此字符串堆排序代码出现分段错误。 知道原因吗?

我在 gdb 中回溯它,我得到了这个

#0  0x0038124b in ?? () from /lib/tls/i686/cmov/libc.so.6
#1  0x08048f62 in heapify(std::string*, int) ()
#2  0x08049050 in heapify(std::string*, int) ()
#3  0x080490ae in BuildMaxHeap(std::string*) ()
#4  0x080490d3 in HeapSort(std::string*) ()
#5  0x080494f5 in main ()

那么,heapify 函数有什么问题呢?

【问题讨论】:

  • Err...你为什么在 C++ 字符串上使用strcmp&lt;/==/&gt;怎么了?
  • 您很可能会超出数组的范围进行阅读。只需放置断点并检查这些数组索引。
  • 我正在使用 > 或
  • 我不认为这与数组的边界有关,因为它可以与其他排序算法一起使用!
  • 仅仅因为它有效并不意味着它是正确的并且永远有效。表现出未定义行为的代码在最重要的时候会咬你一口。

标签: c++ string sorting segmentation-fault heapsort


【解决方案1】:

ifs 中,您应该检查索引是否在数组的范围内您尝试比较字符串之前:

if ( (l < heapSize) && (arr[l] > arr[great]) ) {

【讨论】:

    【解决方案2】:

    这是你的数组索引。查看 leftright 函数以及提供它们的 for 循环参数。使用奇数 'heapSize' 值left 最终将返回数组末尾之后的索引。对于偶数的“heapSize”,right 会做到这一点。

    例如 当 'heapSize' == 15 时,传递给 'heapify' 的最大 'i' 将为 7 ((15-1) / 2)。把它传给'left',你会得到15。对于数组来说太大了,所以在尝试获取'strcmp'的字符串时它会发出嘶哑的声音。

    也许我做错了什么,但无论堆大小如何,我都无法让您的代码运行。

    PS。使用“-g3”标志构建以在 gdb 中获得更好的调试符号。 g++ -g3 heap.cc

    【讨论】:

      猜你喜欢
      • 2016-12-03
      • 1970-01-01
      • 2021-09-17
      • 2021-12-02
      • 1970-01-01
      • 2016-05-24
      • 2021-10-11
      • 1970-01-01
      相关资源
      最近更新 更多