在处理迭代器时被信号SIGSEGV(地址边界错误)终止
terminated by signal SIGSEGV (Address boundary error) when dealing with iterators
我正在尝试实现合并排序算法。首先,我尝试创建merge方法。我使用向量和迭代器。但是merge
函数中的while
主体会导致此错误:
"./a.out"由信号SIGSEGV(地址边界错误(终止
这是代码
#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(&&(not或(||(。这将删除SIGSEGV错误。
2&3:您应该将剩余列表的其余部分添加到合并列表的末尾,而不是最后一个元素之前。
可选更改:
你不需要sorted_tit变量(你没有使用它(
你不必检查是否相等,如果值相等,你可以插入其中的任何一个,循环的下一次迭代就会发挥作用。
你不必检查哪个列表到达了它的末尾,你可以将每个列表的其余部分合并。
以上所有内容都反映在这里:
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;
}
while(first_it != first_vect.end() || second_it != second_vect.end())
您正在迭代,直到:
first_it
等于first_vect.end()
ANDsecond_it
等于second_vect.end()
这两个条件都必须成立。例如,如果first_it
已经到达first_vect.end()
,则迭代将继续,直到second_it
到达其向量的末尾。
if(*first_it < *second_it) {
正如我刚才所解释的,first_it
现在可以等于其向量的end()
迭代器。在这种情况下,在这里取消引用它会导致未定义的行为。
同样的事情也适用于第二个向量的迭代器。
您的逻辑没有考虑到其中一个迭代器已经到达其向量的end()
的可能性。
一种解决方案是将||
转换为&&
,然后在最后添加额外的代码,将任一向量中的任何剩余值附加到输出向量。
解决此问题的另一种方法是调整if()
条件,以考虑迭代器可能是end()
值的可能性,并相应地进行。对于第一个矢量:
if(second_it == second_vect.end() ||
(first_it != first_vect.end() && *first_it < *second_it)) {
但这个逻辑在这里变得有点复杂(以这种方式,两个if
条件都必须检查两个迭代器的边缘情况(。
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 地址的奇怪错误
- 为什么我得到以下代码地址清理器:未知地址错误的SEGV
- 运行时错误:引用绑定到类型"int"的未对齐地址0xbebebebebebebec6,这需要 4 个字节对齐 (stl_vector.h)
- 我有一个线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x8)错误.我认为这是由于内存管理不好.我可以
- Assimp 库错误:获取打包成员的地址
- 运行时错误地址清理器:LEETCODE 中的致命信号
- 瓦尔格林德错误 - 地址0x0不是堆叠的 malloc'd 或自由的
- 循环向量引起的地址边界错误
- 使用结构向量解决边界错误
- 尝试打印 a[1] 的地址时错误:弹出一元'&'操作数时需要左值
- 在 C/C++ 中在特定地址边界上对齐内存是否仍能提高 x86 性能?
- 汇编:C++堆栈变量地址不同/错误?
- C++:尝试将新节点添加到链表会产生"线程 1:EXC_BAD_ACCESS(代码 = 1,地址 = 0x0)"错误
- x86逻辑地址语法错误
- 在C++中使用 STL 时出现边界错误
- 在Linux中使用fork()+execlp和boost::asio时出现地址重用错误
- 为什么我得到协议不支持的地址族错误
- 在处理迭代器时被信号SIGSEGV(地址边界错误)终止
- 在递归函数中被SIGSEGV(地址边界错误)信号终止