对向量使用 Push Back 功能时的分段错误
Posted
技术标签:
【中文标题】对向量使用 Push Back 功能时的分段错误【英文标题】:Segmentation Fault When Using The Push Back Function for a Vector 【发布时间】:2019-11-10 08:20:20 【问题描述】:因此,我尝试从头开始使用自定义哈希函数构建哈希表,但在测试插入函数时遇到了分段错误问题。如果我正确读取了 gdb 输出,则在我的 wn_to_bool 函数中尝试对布尔向量进行推回时会出现问题(取一个整数并将其转换为布尔向量)。我一直在尝试调试这个问题一段时间,但还没有找到解决方案。任何帮助将不胜感激,如有必要,我可以使用调试中引用的其余代码更新帖子。提前谢谢你。
没有新操作符的 GDB 输出
Program received signal SIGSEGV, Segmentation fault.
0x000055555555668b in std::vector<bool, std::allocator<bool> >::push_back (this=0x0, __x=false) at /usr/include/c++/9.2.0/bits/stl_bvector.h:955
955 if (this->_M_impl._M_finish._M_p != this->_M_impl._M_end_addr())
(gdb) bt
#0 0x000055555555668b in std::vector<bool, std::allocator<bool> >::push_back (this=0x0, __x=false) at /usr/include/c++/9.2.0/bits/stl_bvector.h:955
#1 0x0000555555556302 in HashTable<int, int>::wn_to_bool (this=0x7fffffffe3f0, wn=2) at Data_Structures/Hash_Table.cpp:186
#2 0x0000555555556230 in HashTable<int, int>::hashfct (this=0x7fffffffe3f0, key=2) at Data_Structures/Hash_Table.cpp:146
#3 0x0000555555556163 in HashTable<int, int>::insert (this=0x7fffffffe3f0, key=2, value=3) at Data_Structures/Hash_Table.cpp:53
#4 0x0000555555555b0f in main (argc=1, argv=0x7fffffffe4f8) at main.cpp:16
带有新运算符的 GDB 输出
Program received signal SIGABRT, Aborted.
0x00007ffff7ab8f25 in raise () from /usr/lib/libc.so.6
(gdb) bt
#0 0x00007ffff7ab8f25 in raise () from /usr/lib/libc.so.6
#1 0x00007ffff7aa2897 in abort () from /usr/lib/libc.so.6
#2 0x00007ffff7b03758 in __malloc_assert () from /usr/lib/libc.so.6
#3 0x00007ffff7b05f6f in sysmalloc () from /usr/lib/libc.so.6
#4 0x00007ffff7b06d32 in _int_malloc () from /usr/lib/libc.so.6
#5 0x00007ffff7b07e84 in malloc () from /usr/lib/libc.so.6
#6 0x00007ffff7e47cba in operator new (sz=40) at /build/gcc/src/gcc/libstdc++-v3/libsupc++/new_op.cc:50
#7 0x000055555555633d in HashTable<int, int>::wn_to_bool (this=0x7fffffffe3f0, wn=2) at Data_Structures/Hash_Table.cpp:181
#8 0x0000555555556230 in HashTable<int, int>::hashfct (this=0x7fffffffe3f0, key=2) at Data_Structures/Hash_Table.cpp:146
#9 0x0000555555556163 in HashTable<int, int>::insert (this=0x7fffffffe3f0, key=2, value=3) at Data_Structures/Hash_Table.cpp:53
#10 0x0000555555555b0f in main (argc=1, argv=0x7fffffffe4f8) at main.cpp:16
wn_to_bool 函数(请注意 v 最初是一个空向量,因此插入函数将不起作用)
template <typename K, typename V> std::vector<bool>* HashTable<K,V>::wn_to_bool(long wn)
std::vector<bool>* v;
while(wn != 0)
if(wn % 2 == 0)
v->push_back(false);
else
v->push_back(true);
wn = wn / 2;
return v;
【问题讨论】:
v
未初始化,您有一个悬空指针 => 未定义的引用。为什么要使用指向向量的指针?还要小心,vector<bool>
比较奇怪。
"获取一个整数并将其转换为布尔向量" 这是相当可疑的实用程序。为什么需要布尔向量?
【参考方案1】:
请注意 v 最初是一个空向量
事实并非如此。它是一个未初始化的指针。看不到实际的向量。
不要使用原始指针。
抛开这种函数的实用性不谈,这里有一种写法。
template <typename K, typename V>
std::vector<bool> // no pointer
HashTable<K,V>::wn_to_bool(long wn)
std::vector<bool> v; //no pointer
while(wn != 0)
if(wn % 2 == 0)
v.push_back(false);
else
v.push_back(true);
wn = wn / 2;
return v;
因此插入功能将不起作用)
insert
非常适用于空向量,例如 vector<int> v; v.insert(v.begin(), 42)
。
【讨论】:
对不起,插入在哪里?您在回溯中看到的插入方法适用于HashTable
类,但不适用于 std::vector
。本题与insert
方法无关。
@SoheilArmin OP 错误地声称insert
不适用于空的向量。我正在处理这个声明。
很明显,空向量是begin()
等于end()
和push_back
实际上意味着insert(end(),val)
的向量。所以你是绝对正确的。【参考方案2】:
当您执行std::vector<bool>* v
时,您将有一个指向std::vector<bool>
的未初始化指针。这意味着v
具有一些任意值,而没有分配给任何已分配的内存地址。
您需要创建一个new
向量并将其分配给v
。
template <typename K, typename V> std::vector<bool>* HashTable<K,V>::wn_to_bool(long wn)
auto v = new std::vector<bool>();
for(;wn!=0;wm/=2)
v->push_back(wn % 2 != 0);
return v;
您不需要if
语句,因为您直接使用布尔语句的结果。您只需要推回wn%2 != 0
,这比使用if
更有效。您也可以使用for
循环来提高可读性,因为您将在一行代码中编写整个逻辑。
根据 cmets 的建议,在堆内存中创建对象实例(也就是使用 new
)应该非常小心,因为当您不再需要分配的内存时,您必须小心删除它,否则它会导致内存泄漏。强烈建议改用smart pointers。
【讨论】:
对不起,之前没有更具体,但我确实使用你的方法和 std::vector以上是关于对向量使用 Push Back 功能时的分段错误的主要内容,如果未能解决你的问题,请参考以下文章