C++调试记录与心得分享
副标题[/!--empirenews.page--]
之前开发用Linux C比较多,C++中的STL 容器基本没有接触过。最近在学习C++,平时用到c++ 17中的部分新特性,下面就简单分享下自己C++的学习流程。 一、环境搭建 本人使用的是CentOS 7系统,该系统默认的g++版本不支持c++17的新特性。所以,首先需要做的就是升级新版本的g++。 2.安装编译gcc需要的依赖包 3.解压gcc压缩包到temp文件夹 4.进入到temp/gcc目录下,执行 gcc ./configure --enable-checking=release --enable-languages=c,c++ --disable-multilib && make 进行gcc的编译(这个步骤耗时较长) 5.安装新版 6.由于在./configure阶段未指定安装路径,那么新版的gcc的默认安装位置就是/usr/local/目录下,修改标准库的软连接使其指向新版本的标准库 sudo ln -sf /usr/local/lib64/libstdc++.so.6.0.23 /lib64/libstdc++.so.6 7.需要使用c++17的特性时,需要在Makefile的CXXFLAGS变量中添加 -std=c++17 gdb默认情况下是不支持c++容器输出的,不过在gdb 7.0版本之后,可以通过添加插件的方式来支持c++容器输出 add-auto-load-safe-path /usr/local/lib64/libstdc++.so.6.0.23-gdb.py #文件的版本号,根据这个目录中的实际文件版本号确定 import sys sys.path.append("/usr/local/share/gcc-7.1.0/python") sys.path.insert(0,'/home/sxhlinux/.gdb_stl') #注:将第二个参数中的路径改成自己的.gdb_stl文件夹路径 from libstdcxx.v6.printers import register_libstdcxx_printers register_libstdcxx_printers (None) end 二、gdb 调试示例 1.下面的代码是将带有数字特征的分词(用unorder_map保存),按照一定的规则(分词的数字特征)进行合并 #include <iostream> #include <cstdlib> #include <map> #include <unordered_map> using namespace std; template <typename T1,typename T2> bool merge_tokens(T1 &target,const T2 &rules) { auto pre = target.begin(); for (auto token = target.begin(); token != target.end(); ) { if (pre == token) { token ++; continue; } auto range = rules.equal_range(pre->second); auto it = range.first; for (; it != range.second; it++) { if (it->second == token->second) { break; } } if (it == range.second) { pre = token; token ++; } else { pre->first += token->first; // target.insert(std::make_pair<typename T1::key_type,typename T1::mapped_type>(pre->first + token->first,16)); pre->second = 16; token = target.erase(token); pre = token; } } } int main ( int argc,char *argv[] ) { unordered_map<string,size_t> tokens = {{"def",22},{"ghi",100},{"abc",22}}; unordered_multimap<size_t,size_t> rules = {{22,{100,{1,38}}; merge_tokens(tokens,rules); return EXIT_SUCCESS; } /* ---------- end of function main ---------- */ 2. 编译该文件,提示 31行 test.cpp:31:15: error: passing ‘const std::__cxx11::basic_string<char>' as ‘this' argument discards qualifiers [-fpermissive] pre->first += token->first; ~~~~~~~~~~~^~~~~~~~~~~~~~ /usr/local/include/c++/7.1.0/bits/basic_string.h:1122:7: note: in call to ‘std::__cxx11::basic_string<_CharT,_Traits,_Alloc>& std::__cxx11::basic_string<_CharT,_Alloc>::operator+=(const std::__cxx11::basic_string<_CharT,_Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]' operator+=(const basic_string& __str) ^~~~~~~~ 根据错误提示:string 的运算符 += 要求参数是一个 const string类型(作为右值,非const类型也可以作为const类型的参数使用),返回值是一个string类型。再看 出错的语句 pre->first += token->first; 根据mian函数中的tokens的定义,token和pre的first成员都应该是string而不是const string。 3.将报错的这一行注释掉,然后用gdb查看下pre->first和token->first的具体类型。具体如下 (gdb) whatis target type = std::unordered_map<std::__cxx11::basic_string<char,std::char_traits<char>,std::allocator<char> >,unsigned long> & (gdb) whatis target.begin() type = std::unordered_map<std::__cxx11::basic_string<char,unsigned long,std::hash<std::__cxx11::basic_string<char,std::allocator<char> > >,std::equal_to<std::__cxx11::basic_string<char,std::allocator<std::pair<std::__cxx11::basic_string<char,std::allocator<char> > const,unsigned long> > >::iterator (gdb) whatis pre type = std::__detail::_Node_iterator<std::pair<std::__cxx11::basic_string<char,unsigned long>,false,true> (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |