【C++】學習、項目時Debug總結

這里寫目錄標題

  • 1. 內存問題
      • 1.1. 內存泄漏
          • 1.1.1. 內存泄漏案例檢查方法
          • 1.1.2. 主線程提前退出導致【控】
          • 1.1.3. PostThreadMessage失敗導致的內存泄漏**【控】**
          • 1.1.4. SendMessage 時關閉客戶端【控】
          • 1.1.5. 線程機制導致【**控】**
          • 1.1.6. exit(0)導致【控】
      • 1.2. 內存沖突
          • 1.2.1. 內存非法【控】
          • 1.2.2. 訪問內存沖突2【控】
  • 2. 編譯階段問題
      • LINK2005、1169重定義
      • link1120和LNK2019:**無法解析的外部符號**
      • C4996警告
      • C4005宏重定義
      • C2664字符集
      • LNK2001 LNK1120
  • 3. 文件、庫等
      • 3.1. 程序的架構不一致【控】
  • 4. 網絡問題
      • 4.1. **服務端關閉了 socket,但客戶端未closesocket,導致新連接請求被系統拒絕**。 **10056**
      • 4.2. 10054 遠程主機強迫關閉了一個現有的連接。
      • 4.3. 連接失敗:10060 客戶端主動斷開連接,遠程服務端出現bug
  • 5. 調試技巧

1. 內存問題

1.1. 內存泄漏

1.1.1. 內存泄漏案例檢查方法

一個很牛的方法:

  1. 搜索所有的new,然后在其new后打印一下new出來的內存大小,如果有delete,不確定有沒有執行delete,就在delete后打印TRACE(“xxx has been deleteed”);所有都這樣搞,再去執行一遍程序,就能發現哪個沒delete;發現控制類的Instance沒delete,就打斷點看看cHelper的構造和析構有沒有執行;

  2. 打斷點發現都沒執行;查找所有引用發現m_helper只聲明根本就沒實現;然后實現下,實現后就可以執行,內存泄漏的問題解決,

  3. vId使用Visual Leak Detector:

    1. 可以得到內存泄漏點的調用堆棧,如果可以的話,還可以得到其所在文件及行號;
    2. 可以得到泄露內存的完整數據;
    3. 可以設置內存泄露報告的級別;
    4. 它是一個已經打包的lib,使用時無須編譯它的源代碼。而對于使用者自己的代碼,也只需要做很小的改動;
    5. 他的源代碼使用GNU許可發布,并有詳盡的文檔及注釋。對于想深入了解堆內存管理的讀者,是一個不錯的選
1.1.2. 主線程提前退出導致【控】

atlTraceGeneral - m_hwnd = 00000000 —說明窗口句柄未初始化

**debug輸出:**Detected memory leaks!Dumping objects ->{187} normal block at 0x0000025DAB749D20, 90 bytes long. Data:/ 61 00 74 00 6C 00 54 00 72 00 61 00 63 00 65 00

  • 程序崩潰和內存轉儲(Core Dump) 程序運行時,Visual Studio 會在調試模式自動檢測內存泄漏并輸出相關信息。輸出的內存轉儲數據包括了被泄漏的內存塊的地址、大小以及該內存區域的內容。
  • Dumping objects -> 開始輸出(dump)內存中被分配的對象的詳細信息。它通常會顯示當前所有未釋放的內存塊(即潛在的內存泄漏)以及它們的大小、地址等詳細信息。
  • {Object dump complete.} 一行`表示內存泄漏的對象信息已經完全輸出完畢。
  • 表示一個正常的內存塊(不是數組或堆棧),它位于地址 0x0000025DAB749D20,占用 90 字節
  • 這些數據 61 00 74 00 6C 00 54 00 72 00 61 00 63 00 65 00Unicode 編碼的字節表示。每對字節代表一個字符,其中每個字符占 2 字節。 轉換成可讀的字符就是:a t l T r a c e

內存泄漏信息表示在程序運行中分配了內存,但未正確釋放。常見原因:

  • 對象未被銷毀,例如對話框對象未調用 DestroyWindow
  • 動態分配的資源未釋放。

問題原因:

_beginthread 并不提供線程同步功能,它只是啟動一個線程并管理資源 ,導致主線程開啟這個線程后一會主線程執行完結束了,導致程序退出,導致線程強制終止,導致創建的內存還沒來得及釋放。

解決

  • sleep主動阻塞主線程
  • 用thread+join √
1.1.3. PostThreadMessage失敗導致的內存泄漏**【控】**

雖然在SendPack那個線程收到這個new的包復制后就立馬delete,但是萬一發送失敗,就會產生內存泄漏,所以在這地方也要作出處理,那失敗的包怎么處理???

1.1.4. SendMessage 時關閉客戶端【控】

服務端在遠程啟動,關閉客戶端后發現很多鼠標和圖像的內存泄漏,因為客戶端SendPack收到數據后,SendMessage到dlg是new的數據發過去的,如果此時客戶端關閉了,這些new的數據無法釋放,本來處理邏輯是在dlg收到數據后復制一下(棧),然后吧堆區數據給釋放;這種情況怎么辦???

1.1.5. 線程機制導致【控】

線程函數,不管是主線程子線程,對cpu的使用權,記錄一個使用權,main結束是回到系統函數,真正的啟動函數點事mainCRTStartip,調用到main了;

當使用 endthread 來結束線程時,它會直接終止線程,并且不允許線程中的局部變量正常析構(坑的點)。這可能導致內存泄漏或無法釋放的資源,因為局部變量的析構函數不會被調用。 就會導致內存泄漏,現在把這個線程函數的主題放入到另一個函數threadmain里,這樣函數結束就會析構變量,所以一般線程函數里在搞一個函數;線程入口函數(threadQueueEntry)和線程功能函數(threadmain)分開;

解決思路:

  1. 先把所有的new搜一遍,對應的delete是否能對應上。
  2. 確保delete是否執行到?打印日志一般,一般到這問題就出現了
  3. 現在發現delete對沒問題,唯一的可能是list, 當你往 std::list<T> 里添加元素時,每個節點通常都是 在堆區分配的,而 std::list 本身的管理結構體(如 begin 指針、end 指針等)可能位于棧上或堆上,取決于 std::list定義方式
  4. 試著調用list.clear,仍然泄露
  5. 最后百度搜索_endthread的問題,解決方案在上面
1.1.6. exit(0)導致【控】

內存泄漏往往很難定位觸發點,此次情況,new delete對應ok;加日志,所有可能內存泄漏地方加日志分析;

之前這里有個exit(0);函數直接終止,不會 調用當前作用域中的局部變量的析構函數(包括棧上的對象) ,圖中創建的隊列也只會調用構造,不對調用其析構,就導致內存泄漏;和那個endthread是一樣道理;

去掉這個exit后,內存泄漏沒了,但是出現了崩潰的bug;

1.2. 內存沖突

1.2.1. 內存非法【控】

在使用 memcpy 之前,需要確保以下幾點:

  1. 確保 **strData** 的大小足夠: 調用 resize(nSize) 后,strData 的大小應該足夠容納 nSize 字節。
  2. 確保 **pData** 是有效的指針: 在調用 memcpy 前,檢查 pData 是否為空指針。
  3. 確保 **nSize** 合法: 確保 nSize 在合理范圍內,既不能為負值,也不能超過 pData 實際擁有的內存大小。

發現:

pData 的值為 0x00000009,這是一個非常不合理的指針地址(通常有效的指針應該是內存中有效的區域,如堆或棧上的地址),并且調試器提示 讀取字符串時出錯。這說明問題的根本原因是 pData 是一個非法指針。

通過調用堆棧,查看調用這個函數的地方:

發現data是9,傳入的參數,把一個非指針( 整數值 9 )轉為指針,(BYTE*)data 并不是指向有效內存區域的指針,而是一個直接指向地址 0x00000009 的指針,這顯然是非法的。

經驗: 所以以后看到0x00000009 這樣的非法指針,很有可能是把一個數據強轉為指針然后傳了。

經驗2:報錯系統庫函數里的變量內存訪問沖突,發現其內存是0x000005b8,這顯然是個不合法內存;

這種情況就看調用堆棧,觀察自己的代碼哪里開始出錯;發現在控制類的InitController里的this指針是空指針;

合法內存地址通常看起來是較大的十六進制值

常見的非法地址包括:

  • 0x00000000:空指針。
  • 0x000005b8:屬于操作系統保護的低地址區域。
  • 0xdeadbeef0xcccccccc:調試環境中常用的未初始化指針標記。
  • 非法越界地址,例如訪問數組時超出范圍。
1.2.2. 訪問內存沖突2【控】

四個參數里,其他三個是上面定義的局部變量,肯定沒問題,那問題只能處在成員變量m_hCompletionPort,調用堆棧向前分析:

發現thiz指針非法;那就是線程函數傳遞進來的參數有問題;

傳錯了,應該傳的this指針,才能去調用其成員變量;問題根源是直接ctrl c過來的,現在把這些東西都封裝在類里面,線程函數傳的參數也應該改變!

2. 編譯階段問題

  1. 遇到編譯問題不要慌,一個一個解決

  2. 解決的方法:

  3. 調整頭文件的順序(宏沖突)(windows.h 的宏污染(如 min/max)或 C++ 標準庫沖突)22222222222222

  4. 對應的庫文件的引用(LNK2019 無法解析的外部符號錯誤)

  5. #pragma comment(lib, “rpcrt4.lib”) // 顯式鏈接庫

  6. 4996 的警告一般可以通過警告本身的提示,添加宏來解決

  7. #define _CRT_SECURE_NO_WARNINGS // 禁用安全警告

  8. 頭文件引用錯誤(若無法跳轉到定義,說明路徑錯誤或文件缺失)

調試問題總結:

1 socket 返回-1 而參數沒有問題,那么有可能是 WSAStartup 未調用

2 很多時候,問題是疊加在一起的,只要不斷的解決,總能搞定

3 沒有測試的程序,是不靠譜的,無論誰寫的

4 大膽假設,小心求證

LINK2005、1169重定義

外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

其實就是在頭文件聲明和定義了函數,在多個.cpp文件#include這個頭文件就會報錯,出個定義,違反了ODR原則。

解決辦法

  • 函數聲明與定義分離,聲明在頭文件,定義在 .cpp 文件
  • 將函數聲明為 **inline** 如果你需要在頭文件中定義函數(例如,函數實現非常簡單),可以將其聲明為 inline,讓編譯器將其視為內聯函數,不會重復定義: 注意:inline 適用于小型、簡單的函數。如果函數較大或復雜,建議不要內聯。
  • 將函數聲明為 全局static,使其作用域限制在當前編譯單元(每個 .cpp 文件生成獨立副本)
  • 定義為一個類的靜態函數

link1120和LNK2019:無法解析的外部符號

1、無法解析的外部符號,基本上都是聲明了函數,但是沒有定義這個函數外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳

LNK2019

無法解析的外部符號 _main,函數 “int __cdecl invoke_main(void)” (invoke_main@@YAHXZ) 中引用了該符號

  • 這通常意味著鏈接器找不到程序的入口點 main 函數

  • 未定義main函數

  • 展開 鏈接器 > 系統,查看 子系統 選項:

  • 如果您正在寫控制臺程序,確保子系統設置為 Console (/SUBSYSTEM:CONSOLE)。

  • 如果是 Windows 應用程序,確保子系統設置為 Windows (/SUBSYSTEM:WINDOWS)。

  • 根據項目類型,實現相應的入口函數:

  • 對于控制臺程序,定義 main 函數。

  • 對于 Windows 程序,定義 WinMain 函數

發現是入口點函數寫成了main,但是客戶端mfc項目是以winmain為起點的

2、 RTSPServer.obj : error LNK2019: 無法解析的外部符號 __imp**__UuidCreate@4,函數 “public: __thiscall RTSPSession::RTSPSession(class ESocket const &)**” (??0RTSPSession@@QAE@ABVESocket@@@Z) 中引用了該符號 :

  • 通常是由于 未正確鏈接 RPC 運行時庫函數聲明與實現不匹配 導致的
  • UuidCreate 是 Windows RPC 運行時庫中的函數,其聲明位于 rpcdce.hrpc.h,實現位于 rpcrt4.lib。若未正確鏈接該庫,或未包含頭文件,會引發此錯誤
  • 解決:
#pragma comment(lib, "rpcrt4.lib")  // 添加此行到引用 UuidCreate 的源文件或頭文件中

或在項目屬性中配置鏈接庫:

  1. 右鍵項目 → 屬性鏈接器輸入附加依賴項 → 添加 rpcrt4.lib 2 6
  2. 確保 rpcrt4.lib 的路徑正確(如 C:\Program Files (x86)\Windows Kits\10\Lib\...

缺網絡庫:#pragma comment(lib, “ws2_32.lib”)

3、

  1. 報錯:
  2. 此時頭文件目錄,靜態庫都配到 vs 項目里,dll 也配到環境變量
  3. 發現這些庫是 release 版本,vs 使用 debug 模式,改為 release 后,報錯變化為下:

C4996警告

C4996 是 Visual Studio 編譯器的一個警告代碼,用于指示一些被 Microsoft 標記為不安全或已過時的函數。例如scanf等sprintf

inet_addr 函數已被視為過時。推薦使用 inet_pton()

項目里面禁用4996警告三種方法:

  1. 禁用SDL檢查Security Development Lifecycle Checks)可以解決;不推薦長期禁用 SDL 檢查:SDL 檢查的目的是幫助開發者編寫更安全的代碼。
  2. 項目屬性里編譯器預處理那定義,在這里加上去個 _WINSOCK_DEPRECATED_NO_WARNINGS; 來禁用與過時 API 相關的警告
  3. 文件內部定義#pragma warning(disable:4996)

C4005宏重定義

  1. 頭文件順序問題:
  • windows.h 文件在 Windows 平臺中定義了大量的宏和類型,這些宏可能與套接字頭文件中的定義沖突。
  • 例如,windows.h 可能會定義 minmax 宏,與其他頭文件中的定義沖突。
  • 解決:將套接字的頭文件(如 winsock2.hsys/socket.h)放在 windows.h 前面

C2664字符集

解決方法:vs字符集改為多字符集即可

LNK2001 LNK1120

image.png

  • LNK1120:共9個未解析的外部符號(函數/變量)
  • LNK2001:具體列出缺失的FFmpeg API:
問題類型具體表現典型場景
庫文件未鏈接缺少avformat.lib等靜態庫項目配置遺漏
函數聲明不匹配頭文件與庫版本不一致升級FFmpeg后未更新頭文件
編譯架構沖突x86庫用于x64項目平臺配置錯誤

當C++代碼調用C語言庫(如FFmpeg)時,必須使用此語法包裹C語言的頭文件。

extern "C" { 
#include <libavformat/avformat.h> 
#include <libavcodec/avcodec.h> 
}
  • C++ 語言支持函數重載等特性,編譯器在編譯時會對函數名進行 “名字改編(Name Mangling)”,將函數名和參數類型等信息混合生成內部使用的符號名,以此區分同名但參數不同的函數。而 C 語言不支持函數重載,沒有名字改編機制 ,函數名就是實際鏈接時使用的符號名。
  • FFmpeg 庫(libavcodeclibavformat是其相關庫)是用 C 語言編寫的,為了能在 C++ 代碼中(.cpp文件里)正確調用 FFmpeg 庫中的 C 函數,需要告訴 C++ 編譯器,這部分代碼要按照 C 語言的規則進行編譯,避免名字改編帶來的鏈接錯誤,extern "C"就是起這個作用。

3. 文件、庫等

3.1. 程序的架構不一致【控】

一個典型的 Windows 錯誤,錯誤代碼為 0xc000007b,提示程序無法正常啟動 :

  1. 確保程序的架構(32 位或 64 位)與所有依賴的 DLL 的架構一致。

發現正是這個問題導致!

4. 網絡問題

recv 返回 -1 時的錯誤碼

  • **WSAECONNRESET** (10054)

  • 服務端主動關閉了連接,導致客戶端讀取數據失敗。

  • 或者,服務端異常退出,連接被 TCP 重置。

  • **WSAETIMEDOUT** (10060)

  • 接收超時,客戶端等待服務端的數據時超時。

  • **WSAENOTCONN** (10057)

  • 套接字未連接,可能是客戶端在連接斷開后嘗試接收數據。

  • **WSAEINTR**

  • 接收操作被中斷。

4.1. 服務端關閉了 socket,但客戶端未closesocket,導致新連接請求被系統拒絕10056

10056 在一個已經連接的套接字上做了一個連接請求

1、發現客戶端也closesocket之后再connect就能連上了,這是為啥????

  • **closesocket** 釋放了客戶端的本地端口

  • 當客戶端調用 closesocket() 時,本地的套接字資源被立即釋放,包括綁定的本地端口。

  • 此時,客戶端可以立即創建一個新的套接字,并發起 connect 操作。

  • 因為新的套接字使用了新的資源,與之前的舊套接字無關,因此不會有沖突。

  • 服務端的端口可以接受新的連接

  • 服務端雖然進入了 TIME_WAIT 狀態,但 TIME_WAIT 并不影響服務端套接字接受新的連接請求。

  • TIME_WAIT 只會限制服務端重用之前的連接,而不會阻止服務端監聽套接字接受新的連接。

  • 新的套接字使用了新的連接三元組

  • 每個 TCP 連接由三元組 (客戶端 IP, 客戶端端口, 服務端 IP:服務端端口) 唯一標識。

  • 當客戶端創建新的套接字時,系統會為其分配一個新的客戶端端口(如果沒有指定),使新的連接三元組和舊的連接三元組完全獨立,從而不會沖突。

  • 網絡資源釋放及時

  • 客戶端調用 closesocket() 時,系統通常會立即釋放該套接字的本地端口資源,而無需等待 TIME_WAIT

2、如果客戶端等待 2 分鐘(或者操作系統配置的 TIME_WAIT 時間)讓服務端的 TIME_WAIT 狀態過去后, 客戶端在 不調用 **closesocket()** 的情況下,直接使用同一個套接字句柄 (socket) 再次調用 connect,這種行為是 非法的,并且會導致 **connect** 調用失敗,報錯 **WSAEISCONN****WSAENOTSOCK**,具體原因如下:

  • **socket** 的狀態已經是已連接

  • 在 TCP 協議中,當客戶端完成一次 connect 后,該套接字已經綁定到特定的連接三元組 (本地IP, 本地端口, 服務端IP:服務端端口)

  • 套接字資源仍然有效,但它已經與之前的連接綁定。

  • 如果此時服務端已經關閉連接,而客戶端沒有關閉套接字,卻嘗試再次調用 connect

  • 操作系統會檢查套接字的狀態,發現它仍然處于連接綁定狀態,而不是一個空閑的套接字。

  • 此時調用 connect 會報錯 **WSAEISCONN**(表示該套接字已連接)。

  • 服務端的 **TIME_WAIT** 不影響這個行為

  • 服務端的 TIME_WAIT 狀態與客戶端無關。客戶端的行為取決于其套接字資源的狀態。

  • 如果客戶端的套接字仍然有效,但已經綁定到舊的三元組,則不能直接使用該套接字重新連接。

  • 客戶端的操作系統規則

  • 操作系統對 TCP 套接字的狀態有嚴格的定義,一個已連接的套接字不能被用于發起新的連接

  • TCP 套接字的生命周期如下:

  1. **socket()**:創建套接字,分配資源。
  2. **connect()**:與服務端建立連接,綁定三元組。
  3. **closesocket()**:關閉套接字,釋放綁定的三元組。
  • 如果沒有調用 closesocket(),操作系統仍然認為該套接字與之前的連接綁定,即使服務端關閉連接,客戶端也無法重新使用該套接字。

4.2. 10054 遠程主機強迫關閉了一個現有的連接。

本機聯調進行testConnection通信沒問題,但是服務端放在虛擬機上,就報這個報錯!

已知錯誤碼10054

  • **WSAECONNRESET** (10054)

  • 服務端主動關閉了連接,導致客戶端讀取數據失敗。

  • 或者,服務端異常退出,連接被 TCP 重置。

難繃,客戶端第一次connect服務端返回成功,send也沒報錯,recv報錯了,但是發現ping不通虛擬機,那為啥客戶端第一次connect會返回0呢;ping不同是因為主機換wifi了,網段變了,但之前虛擬機設置了靜態ip,橋接模式下虛擬機和宿主機網段一樣才能ping通,

改了ip后,CS網絡通信正常了!

可能回答:

虛擬機的 IP 靜態配置沒有影響初始連接

  • 雖然虛擬機設置了靜態 IP,但當宿主機切換 Wi-Fi 導致網段改變時,虛擬機和宿主機可能仍然在某種程度上保持通信能力。
  • 原因:在某些橋接模式下,虛擬機和宿主機可能會嘗試使用舊的 ARP 緩存或其他機制進行通信,允許一部分數據包通過,尤其是初始的 TCP 握手。
  • 但后續的數據包可能因網段不一致而丟失。

為什么 **send** 沒報錯?

  • TCP 的發送緩沖區行為 當客戶端調用 send 時,數據會先被放入操作系統的發送緩沖區,立即返回成功。
  • 如果 TCP 的狀態仍然是 ESTABLISHED,操作系統不會立即檢查數據是否成功到達服務端。
  • 即使 send 成功,數據可能無法到達服務端,因為網段不一致或路由配置錯誤導致數據包被丟棄。
  • 當客戶端調用 recv 時,操作系統檢測到連接被服務端關閉,返回錯誤碼 10054

為什么 recv 報錯?

  • 由于虛擬機的 IP 地址錯誤,服務端可能接收不到客戶端發送的數據,誤認為客戶端超時,主動關閉了連接。
  • 服務端關閉連接后,客戶端的 recv 會報錯 10054,表示連接被重置。

4.3. 連接失敗:10060 客戶端主動斷開連接,遠程服務端出現bug

1 由于連接方在一段時間后沒有正確答復或連接的主機沒有反應,連接嘗試失敗

LISTENING 狀態僅表示服務端已經調用了 listen 并正在監聽指定端口。

如果套接字是默認的阻塞模式,調用 recv 時:

  • 如果接收緩沖區中有數據,recv 會立即返回已接收的數據字節數。
  • 如果緩沖區中沒有數據,recv 會阻塞當前線程,直到:
  1. 數據可用。
  2. 連接被對端關閉(返回 **0**。或者設置接受0長度那也返回0; 當服務端的 recv 函數返回 0 時,表示 對端(客戶端)已經優雅地關閉了連接,即發送了一個 FIN 包。對于這種情況: recv 返回 0 是一次性的。 如果繼續調用 recv,通常會返回 **-1**,并設置錯誤碼(如 EINVAL 或類似錯誤),提示該套接字已失效。
  3. 發生錯誤(返回 -1)。

問題:本機聯調客戶端和服務器沒問題,服務端放遠程后一直啟動,客戶端第一次啟動也沒問題,但第二次啟動發現服務端在dealcommand里死循環,無法再次進入accept函數里導致客戶端connect時候報錯10060;

**那為啥死循環?
**:發現多次客戶端測試網絡通信,服務端accept返回的m_client都是552???總不能每次都復用552吧;

客戶端這邊每次發送新的命令,使用的socket會變,只是偶爾復用原來的socket;

死循環是因為客戶端關閉后,應該要return后重新accept新的客戶端,但代碼邏輯還一直在recv recv循環,邏輯問題;

為什么 **recv** 會一直頻繁返回 **0**

recv 返回 0 時,說明對端(客戶端)已經優雅地關閉了連接(發送了 FIN 包)。但在 **recv** 返回 **0** 之后,套接字仍然是合法的(并沒有直接closesocket,才會發fin)還可以收數據,因此你可以繼續對這個套接字調用 recv,而它仍然可能返回 0

  • 阻塞行為在這種情況下不適用,因為套接字已經進入了一種特殊狀態(“對端關閉但本端未關閉”),所以 recv 不會再阻塞。
  • 如果服務端繼續調用 recv,TCP 協議層會立即返回 0,表示對端已經關閉發送方向。

為什么沒有返回 **-1**

**-1** 是錯誤的標志,而不是連接關閉的標志

  • 當發生網絡錯誤套接字非法時 ,recv 返回 -1
  • 對于對端優雅關閉的情況(發送了 FIN 包),recv 不會返回 -1,因為這是正常的 TCP 關閉行為,不是錯誤。
  • 阻塞行為在這種情況下不適用,因為套接字已經進入了一種特殊狀態(“對端關閉但本端未關閉”),所以 recv 不會再阻塞。

解決:

直接return,客戶端都斷開了還while個屁,需要return然后服務端再次進入accept阻塞等待新的客戶端連接;

但是為啥本機調試時候沒出現這個問題呢:

本機調試,客戶端關閉時候,服務端肯定也是一起關閉的,死循環雖有但是關閉后看不到了罷了;

5. 調試技巧

  1. send()之后,如果想知道send多少數據,直接在寄存器eax里查看就行/
  2. InitSocket執行時候出問題了,可以右鍵這個函數:設置下一條語句,直接進去走一遍檢查
  3. 斷點中加條件,例如在循環里執行到某次時候斷點,或者遍歷數據集時候的某個數據打斷點或者這個循環命中次數
  4. 調用堆棧窗口的重要功能是:可以找到當前函數的調用函數,以及依次往前的每一級調用函數。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82635.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82635.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82635.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2025 后端自學UNIAPP【項目實戰:旅游項目】1、創建項目框架

1、創建項目 ①項目名稱&#xff1a;自定義&#xff0c;【我是travel】 ②vue版本&#xff1a;vue3 ③其他默認&#xff0c;最后創建 2、創建頁面 ①展開自己剛才創建的項目 ②單擊選中pages文件夾 --->鼠標右鍵---->新建頁面 ③頁面名稱&#xff1a;自定義favouri…

WPF 子界面修改后通知到主頁面

子頁面&#xff1a; public partial class MyPopupWindow : Window { public event Action OnClose; private void CloseWindowButton_Click(object sender, RoutedEventArgs e) { OnClose?.Invoke(); this.Close(); } } 主界面&#xff1a…

Python中的標識、相等性與別名:深入理解對象引用機制

在Python編程中&#xff0c;理解變量如何引用對象以及對象之間的比較方式是至關重要的基礎概念。本文將通過Lewis Carroll的筆名示例&#xff0c;深入探討Python中的對象標識、相等性判斷以及別名機制。 別名現象&#xff1a;變量共享同一對象 >>> charles {name: …

python 閉包獲取循環數據經典 bug

問題代碼 def create_functions():functions []for i in range(3):# 創建一個函數,期望捕獲當前循環的i值functions.append(lambda: print(f"My value is: {i}"))return functions# 創建三個函數 f0, f1, f2 create_functions()# 調用這些函數 f0() # 期望輸出 &…

克里金模型+多目標優化+多屬性決策!Kriging+NSGAII+熵權TOPSIS!

目錄 效果一覽基本介紹程序設計參考資料 效果一覽 基本介紹 克里金模型多目標優化多屬性決策&#xff01;KrigingNSGAII熵權TOPSIS&#xff01;&#xff01;matlab2023b語言運行&#xff01; 1.克里金模型&#xff08;Kriging Model&#xff09;是一種基于空間統計學的插值方法…

Prompt Engineering 提示詞工程學習

一、Prompt Engineering 簡介 Prompt Engineering 是設計和優化輸入提示(Prompt)以獲得預期輸出的過程。在與大型語言模型(如 GPT-4)交互時,如何構造提示會顯著影響模型的回答質量。 二、Prompt 的重要性 提高生成準確性:通過正確的 Prompt 引導,模型能夠更好地理解用…

MATLAB安裝常見問題及解決方案詳解(含代碼示例)

MATLAB作為科學計算和工程分析的核心工具&#xff0c;其安裝過程可能因操作系統版本、硬件配置或網絡環境等因素而出現各種問題。本文基于MATLAB官方文檔和社區經驗&#xff0c;系統總結了安裝過程中常見的問題&#xff0c;并提供詳細的解決方案和代碼示例&#xff0c;幫助用戶…

免安裝 + 快速響應Photoshop CS6 精簡版低配置電腦修圖

各位PS小白和修圖大神們&#xff0c;今天來給大家聊聊Photoshop CS6精簡版這個寶藏軟件&#xff01; Photoshop CS6精簡版就是Adobe Photoshop CS6的“瘦身版”&#xff0c;它把一些不常用的功能給簡化了&#xff0c;只留下核心工具&#xff0c;特別適合那些想高效操作、節省系…

微服務架構實戰:從服務拆分到RestTemplate遠程調用

微服務架構實戰&#xff1a;從服務拆分到RestTemplate遠程調用 一 . 服務拆分1.1 服務拆分注意事項1.2 導入服務拆分 Demo1.3 小結 二 . 服務間調用2.1 注冊 RestTemplate2.2 實現遠程調用2.3 小結 三 . 提供方和消費方 在分布式系統設計中&#xff0c;微服務架構因其靈活性、可…

MySQL 索引與事務詳解

目錄 一、索引&#xff08;Index&#xff09; 二、事務&#xff08;Transaction&#xff09; 三、總結 一、索引&#xff08;Index&#xff09; 索引的本質&#xff1a;一種數據結構&#xff08;如 BTree、Hash&#xff09;&#xff0c;用于快速定位數據&#xff0c;避免全…

macOS Python 環境配置指南

1. 檢查現有 Python 環境 python3 --version # 檢查 Python 3 版本 pip3 --version # 檢查 pip 版本 2. 安裝 pyenv&#xff08;Python 版本管理工具&#xff09; # 使用 Homebrew 安裝 pyenvbrew install pyenv# 配置 pyenv 環境變量&#xff08;添加到 ~/.zshrc&#…

游戲引擎學習第272天:顯式移動轉換

回顧并為今天的內容鋪墊背景 我們剛開始為游戲主角編寫一些程序邏輯&#xff0c;因為我們之前已經完成了大部分引擎方面的開發&#xff0c;現在可以專注在角色身上。這個角色的移動方式會有些特別&#xff0c;與大多數游戲角色的運動機制不太一樣。我們當前正在實現的控制方式…

軟件測試都有什么???

文章目錄 一、白盒測試&#xff08;結構測試&#xff09;二、黑盒測試&#xff08;功能測試&#xff09;三、灰盒測試四、其他測試類型五、覆蓋準則對比六、應用場景 軟件測試主要根據測試目標、技術手段和覆蓋準則進行分類。分為白盒測試、黑盒測試、灰盒測試及其他補充類型 一…

very_easy_sql(SSRF+SQL注入)

題目有一行提示&#xff1a; you are not an inner user, so we can not let you have identify~&#xff08;你不是內部用戶&#xff0c;所以我們不能讓你進行身份驗證&#xff09;聯想到可能存在SSRF漏洞&#xff0c;一般情況下&#xff0c;SSRF攻擊的目標是外網無法訪問的內…

國內外主流AI編程工具全方位對比分析(截至2025年5月)

一、國際主流工具對比 1. Windsurf&#xff08;Codeium公司&#xff09; 核心功能&#xff1a;代理型AI編程&#xff08;代碼導航/修改/命令執行&#xff09;、瀏覽器DOM訪問、網頁研究功能語言支持&#xff1a;70語言&#xff0c;包括Python/Java/JavaScript/Rust等[[22-23]…

ARP協議的工作原理

文章目錄 ARP協議的工作原理ARP報文&#xff08;以太網&#xff09;ARP高速緩存 ARP協議的工作原理 ARP協議的作用是實現任意網絡層地址到任意物理地址轉換。工作原理是&#xff1a; 主機向自己所在網絡廣播一個ARP請求&#xff0c;該請求包含目標機器的網絡地址。處于該網絡…

【小知識酷】《Matlab》考點精簡

在線編譯器 https://matlab.mathworks.com/?elqsidumic49viv8wu5r6fckew 第1章 matlab基礎知識 第1節 輸出函數 1. 使用disp函數 disp函數可用于輸出變量的值或者字符串。 % 輸出字符串 disp(Hello, MATLAB!); %顯示Hello, MATLAB!% 輸出變量 x 10; disp(x); %顯示10% 輸出數…

碼蹄集——中庸之道(三個數比較)

MT1112 中庸之道 請編寫一個簡單程序&#xff0c;輸入3個整數&#xff0c;比較他們的大小&#xff0c;輸出中間的那個數 格式 輸入格式&#xff1a; 輸入整型&#xff0c;空格分隔 輸出格式&#xff1a;輸出整型 樣例 1 輸入&#xff1a;1 5 3 輸出&#xff1a;3 比較…

快速搭建一個vue前端工程

一、環境準備 1、安裝node.js 下載地址&#xff1a;Node.js 推薦版本如下&#xff1a; 2、檢查node.js版本 node -v npm -v 二、安裝Vue腳手架 Vue腳手架是Vue官方提供的標準化開發工具。vue官網&#xff1a;https://cn.vuejs.org/ 全局安裝vue/cli &#xff08;僅第一次…

React Native基礎環境配置

React Native基礎環境配置 1.引言2.React-Native簡介3.項目基礎環境搭建1.引言 感覺自己掌握的知識面還是有點太窄了,于是決定看看移動端的框架,搞個react搭一個后端管理項目,然后拿react-native寫個小的軟件,試著找個三方上架一下應用市場玩玩。畢竟不可能一直在簡歷上掛一…