c++ - 处理迭代器时由信号 SIGSEGV(地址边界错误)终止

标签 c++ c++11 iterator mergesort segmentation-fault

我正在尝试实现合并排序算法。首先,我尝试创建合并方法。我正在使用 vector 并利用迭代器。但是 merge 函数中的 while 主体会导致此错误:

“./a.out” terminated by signal SIGSEGV (Address boundary error)

这是代码

#include <iostream>
#include <vector>

std::vector<int> merge(std::vector<int> &, std::vector<int> &);

int main()
{
  std::vector<int> vect {1,3,5,7};
  std::vector<int> vect2 {2,3,6,8};
  std::vector<int> temp_vect = merge(vect, vect2);
  for(int num: temp_vect) {
    std::cout << num  << std::endl;
  }

}

std::vector<int> merge(std::vector<int> & first_vect, std::vector<int> & second_vect)
{
  std::vector<int> sorted_vect;
  auto sorted_it = sorted_vect.begin();
  auto first_it = first_vect.begin(), second_it = second_vect.begin();

  while(first_it != first_vect.end() || second_it != second_vect.end()) {
      if(*first_it < *second_it) {
        sorted_vect.push_back(*first_it);
        first_it++;
      } else if(*first_it > *second_it) {
        sorted_vect.push_back(*second_it);
        second_it++;
      } else {
        sorted_vect.push_back(*first_it);
        sorted_vect.push_back(*second_it);
        first_it++; second_it++;
      }
  }

  if(first_it == first_vect.end()) {
    //end of first_vect reached
    //inserting the rest of second_vect
    sorted_vect.insert(sorted_vect.end() - 1, second_it, second_vect.end());
  } else if (second_it == second_vect.end()) {
    //end of second_vect reached
    //inserting the rest of first_vect
    sorted_vect.insert(sorted_vect.end() - 1, first_it, first_vect.end());
  }

  return sorted_vect;
}

最佳答案

通常,当进程尝试访问未分配给该特定进程的内存时,会引发 SIGSEGV。引发 SIGSEGV 的主要原因是取消引用无效指针。在您的情况下,当您在到达该列表的末尾时取消引用first_it或second_it以检查其值时,就会发生这种情况。

您至少需要三项更改:

1: line 23- while(first_it != first_vect.end() && second_it != second_vect.end())
2: line 40- sorted_vect.insert(sorted_vect.end(), second_it, second_vect.end());
3: line 44- sorted_vect.insert(sorted_vect.end(), first_it, first_vect.end());

1:您应该检查是否到达了任何列表的末尾:您应该使用 and (&&) 而不是 or (||)。这将消除 SIGSEGV 错误。

2&3:您应该将剩余列表的其余部分添加到合并列表的末尾,而不是在最后一个元素之前。

可选更改:

  1. 您不需要sorted_it变量(您没有使用它)

  2. 您不必检查是否相等,如果值相等,您可以插入其中任何一个,循环的下一次迭代将发挥作用。

  3. 您不必检查哪个列表到达末尾,您可以合并每个列表的其余部分。

以上所有内容都反射(reflect)在这里:

std::vector<int> merge(std::vector<int> & first_vect, std::vector<int> & second_vect)
{
      std::vector<int> sorted_vect;
      auto first_it = first_vect.begin(), second_it = second_vect.begin();

      while(first_it != first_vect.end() && second_it != second_vect.end()) {
           if(*first_it < *second_it) {
               sorted_vect.push_back(*first_it);
               first_it++;
           } else {
               sorted_vect.push_back(*second_it);
               second_it++;
           }
      }
      sorted_vect.insert(sorted_vect.end(), first_it, first_vect.end());
      sorted_vect.insert(sorted_vect.end(), second_it, second_vect.end());
      return sorted_vect;
}

关于c++ - 处理迭代器时由信号 SIGSEGV(地址边界错误)终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39431422/

相关文章:

java - Java 中的 Lambda 与迭代器

c++ - 在使用英特尔内部函数对 SIMD 代码进行编程时,如何强制使用 vmovapd 而不是 vmovupd?

c++ - 什么时候应该在 C++ 中使用 BOOL 和 bool?

c++ - 为什么数组分配后的堆这么大

c++ - 错误 :sorry, 未实现:在函数模板中使用 decltype 时,函数模板签名中存在字符串文字

c++ - 没有用于方法调用的可行的 std::weak_ptr 到 std::shared_ptr 的转换

c++ - Linux编译代码失败,Windows编译成功 : Cause/Fix?

c++ - 当在右值引用上调用 std::move 时会发生什么?

java - 如何将一个迭代器复制到另一个?

基于现有随机访问迭代器的C++反向迭代器?