欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++調(diào)試記錄與心得分享

 更新時間:2017年07月16日 11:01:05   作者:sxhlinux  
本文給大家詳細記錄了一次C++的調(diào)試過程,以及調(diào)試的心得,非常的實用,有需要的小伙伴可以參考下

 之前開發(fā)用Linux C比較多,C++中的STL 容器基本沒有接觸過。最近在學習C++,平時用到c++ 17中的部分新特性,下面就簡單分享下自己C++的學習流程。

一、環(huán)境搭建

     本人使用的是CentOS 7系統(tǒng),該系統(tǒng)默認的g++版本不支持c++17的新特性。所以,首先需要做的就是升級新版本的g++。
1.到ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/releases/網(wǎng)站上選擇支持c++17的gcc版本,并使用wget下載到Linux系統(tǒng)中:wget ftp://ftp.mirrorservice.org/sites/sourceware.org/pub/gcc/releases/gcc-7.1.0/gcc-7.1.0.tar.bz2

2.安裝編譯gcc需要的依賴包 sudo yum install gmp-devel mpfr-devel libmpc-devel -y

3.解壓gcc壓縮包到temp文件夾  tar -jxf gcc-7.1.0.tar.bz2 -C temp

4.進入到temp/gcc目錄下,執(zhí)行 gcc ./configure --enable-checking=release --enable-languages=c,c++ --disable-multilib && make 進行g(shù)cc的編譯(這個步驟耗時較長)

5.安裝新版gcc  sudo make install

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++容器輸出
1.檢查gdb版本 gdb --version, (如果版本號低于7.0就不用往下看了)
2.在當前用戶的home目錄中(如/home/sxhlinux)下載 插件代碼 svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python (沒有svn的,需要通過 sudo yum install svn -y 安裝)然后執(zhí)行mv python .gdb_stl 將該文件夾重命名(使其隱藏)
3.執(zhí)行 vim ~/.gdbinit,編輯gdb配置文件,添加如下內(nèi)容

add-auto-load-safe-path /usr/local/lib64/libstdc++.so.6.0.23-gdb.py  #文件的版本號,根據(jù)這個目錄中的實際文件版本號確定

import sys
sys.path.append("/usr/local/share/gcc-7.1.0/python")
sys.path.insert(0, '/home/sxhlinux/.gdb_stl')   #注:將第二個參數(shù)中的路徑改成自己的.gdb_stl文件夾路徑
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end 

二、gdb 調(diào)試示例

1.下面的代碼是將帶有數(shù)字特征的分詞(用unorder_map保存),按照一定的規(guī)則(分詞的數(shù)字特征)進行合并

#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}, {100, 22}, {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, _Traits, _Alloc>::operator+=(const std::__cxx11::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>]'

       operator+=(const basic_string& __str)

       ^~~~~~~~

     根據(jù)錯誤提示:string 的運算符 += 要求參數(shù)是一個 const string類型(作為右值,非const類型也可以作為const類型的參數(shù)使用),返回值是一個string類型。再看 出錯的語句 pre->first += token->first; 根據(jù)mian函數(shù)中的tokens的定義,token和pre的first成員都應(yīng)該是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, std::char_traits<char>, std::allocator<char> >, unsigned long, std::hash<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::equal_to<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unsigned long> > >::iterator

(gdb) whatis pre

type = std::__detail::_Node_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, unsigned long>, false, true> 

     根據(jù)上面顯示的,target兩個參數(shù)類型確實和定義的一樣,string和unsigned long;target.begin()類型說明中的std::allocator的模板參數(shù)pair的第一個參數(shù)為 string const,說明在創(chuàng)建unordered_map時,key的類型為const string而不是string(猜測這跟map與key相關(guān)的只有增加、刪除而沒有修改操作有關(guān))。因為allocator在申請空間時,已經(jīng)隱式的將string轉(zhuǎn)成了const string,所以,pre->first的類型是const string而不是string(也就無法進行+=,=等相關(guān)操作)。

 
4.根據(jù)第三步的分析結(jié)果,要實現(xiàn)合并元素的效果,只能是將合并后的值作為一個新的pair插入到原來的map中,然后將原來的兩個pair刪除。代碼如下:

target.insert(std::make_pair<typename T1::key_type, typename T1::mapped_type>(pre->first + token->first, 16));

target.erase(pre);

token = target.erase(token);

pre = token; 

三、總結(jié)

     很多時候我們遇到問題首先想到的是將錯誤復(fù)制下來,然后粘貼到google搜索框中,漫無目的的去尋找答案,而不是仔細分析查看gcc給出的錯誤提示。跟我的經(jīng)驗,很多時候gcc給出的提示相當明顯,認真仔細閱讀大部分可以很快找出解決方案,剩余的一部分棘手問題可以借助搜索引擎(PS:當搜索英文提示時,如果沒有g(shù)oogle,可以使用英文版的必應(yīng),效果也不錯)

相關(guān)文章

  • C++的內(nèi)聯(lián)函數(shù)你了解嗎

    C++的內(nèi)聯(lián)函數(shù)你了解嗎

    這篇文章主要為大家詳細介紹了C++的內(nèi)聯(lián)函數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C++ Template 基礎(chǔ)篇(一):函數(shù)模板詳解

    C++ Template 基礎(chǔ)篇(一):函數(shù)模板詳解

    這篇文章主要介紹了C++ Template函數(shù)模板,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • C++ push方法與push_back方法常見方法介紹

    C++ push方法與push_back方法常見方法介紹

    push與push_back是STL中常見的方法,都是向數(shù)據(jù)結(jié)構(gòu)中添加元素,本文還將簡述push對應(yīng)的stack與queue系列,常見方法的介紹,以及與push_back相對應(yīng)的vector系列常見方法介紹,感興趣的朋友跟隨小編一起看看吧
    2022-11-11
  • C語言遞歸之漢諾塔和青蛙跳臺階問題

    C語言遞歸之漢諾塔和青蛙跳臺階問題

    這篇文章主要介紹了C語言遞歸之漢諾塔問題和青蛙跳臺階問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • C/C++標準庫之轉(zhuǎn)換UTC時間到local本地時間詳解

    C/C++標準庫之轉(zhuǎn)換UTC時間到local本地時間詳解

    最近遇到一個問題:數(shù)據(jù)庫中存放的時間為UTC時間,但是現(xiàn)在要求都出來顯示的時間為本地時間,所以就用C++實現(xiàn)了,下面這篇文章主要給大家介紹了關(guān)于C/C++標準庫之轉(zhuǎn)換UTC時間到local本地時間的方法,還有C++中獲取UTC時間精確到微秒的實現(xiàn)代碼,需要的朋友可以參考下。
    2017-11-11
  • C語言:利用指針編寫程序,用梯形法計算給定的定積分實例

    C語言:利用指針編寫程序,用梯形法計算給定的定積分實例

    今天小編就為大家分享一篇C語言:利用指針編寫程序,用梯形法計算給定的定積分實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • VS2019如何添加頭文件路徑的方法步驟

    VS2019如何添加頭文件路徑的方法步驟

    這篇文章主要介紹了VS2019如何添加頭文件路徑的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-08-08
  • C/C++ 公有繼承、保護繼承和私有繼承的對比詳解

    C/C++ 公有繼承、保護繼承和私有繼承的對比詳解

    這篇文章主要介紹了C/C++ 公有繼承、保護繼承和私有繼承的區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • C++從一個文件夾中讀出所有txt文件的方法示例

    C++從一個文件夾中讀出所有txt文件的方法示例

    這篇文章主要給大家介紹了關(guān)于C++從一個文件夾中讀出所有txt文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2018-03-03
  • C++ assert()函數(shù)用法案例詳解

    C++ assert()函數(shù)用法案例詳解

    這篇文章主要介紹了C++ assert()函數(shù)用法案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-09-09

最新評論