【C++】学习、项目时Debug总结

news2025/5/12 19:57:08

这里写目录标题

  • 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.coloradmin.cn/o/2374167.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

26考研——中央处理器_指令流水线_指令流水线的基本概念 流水线的基本实现(5)

408答疑 文章目录 六、指令流水线指令流水线的基本概念流水线的基本实现流水线设计的原则流水线的逻辑结构流水线的时空图表示 八、参考资料鲍鱼科技课件26王道考研书 六、指令流水线 前面介绍的指令都是在单周期处理机中采用串行方法执行的&#xff0c;同一时刻 CPU 中只有一…

AI Agent-基础认知与架构解析

定义 AI Agent 可以理解为一种具备感知、决策和行动能力的智能实体&#xff0c;能够在复杂的环境中自主运行&#xff0c;并根据环境变化动态调整自身行为&#xff0c;以实现特定目标。与传统的人工智能程序相比&#xff0c;AI Agent 具有更强的自主性、交互性和适应性。它不仅能…

C语言--字符函数

C语言--字符函数 一、字符函数1.1 iscntrl1.2 isspace1.3 isdigit1.4 isxdigit1.5 islower1.6 isupper1.7 isalpha1.8 isalnum1.9 ispunct1.10 isgraph1.11 isprint 在编程的过程中&#xff0c;我们会经常处理字符&#xff0c;为了方便操作&#xff0c;C语言标准库中提供了一系…

菜鸟之路Day30一一MySQL之DMLDQL

菜鸟之路Day30一一MySQL之DML&DQL 作者&#xff1a;blue 时间&#xff1a;2025.5.8 文章目录 菜鸟之路Day30一一MySQL之DML&DQL一.DML0.概述1.插入语句&#xff08;insert&#xff09;2.更新语句&#xff08;update&#xff09;3.删除语句&#xff08;delete&#xf…

基 LabVIEW 的多轴电机控制系统

在工业自动化蓬勃发展的当下&#xff0c;多轴伺服电机控制系统的重要性与日俱增&#xff0c;广泛应用于众多领域。下面围绕基于 LabVIEW 开发的多轴伺服电机控制系统展开&#xff0c;详细阐述其应用情况。 一、应用领域与场景 在 3D 打印领域&#xff0c;该系统精确操控打印头…

《Go小技巧易错点100例》第三十二篇

本期分享&#xff1a; 1.sync.Map的原理和使用方式 2.实现有序的Map sync.Map的原理和使用方式 sync.Map的底层结构是通过读写分离和无锁读设计实现高并发安全&#xff1a; 1&#xff09;双存储结构&#xff1a; 包含原子化的 read&#xff08;只读缓存&#xff0c;无锁快…

需求分析阶段测试工程师主要做哪些事情

在软件测试需求分析阶段&#xff0c;主要围绕确定测试范围、明确测试目标、细化测试内容等方面开展工作&#xff0c;为后续测试计划的制定、测试用例的设计以及测试执行提供清晰、准确的依据。以下是该阶段具体要做的事情&#xff1a; 1. 需求收集与整理 收集需求文档&#x…

项目模拟实现消息队列第二天

消息应答的模式 1.自动应答: 消费者把这个消息取走了&#xff0c;就算是应答了&#xff08;相当于没有应答) 2.手动应答: basicAck方法属于手动应答(消费者需要主动调用这个api进行应答) 小结 1.需要实现生产者,broker server&#xff0c;消费者这三个部分的 2.针对生产者和消费…

5.Redission

5.1 前文锁问题 基于 setnx 实现的分布式锁存在下面的问题&#xff1a; 重入问题&#xff1a;重入问题是指 获得锁的线程可以再次进入到相同的锁的代码块中&#xff0c;可重入锁的意义在于防止死锁&#xff0c;比如 HashTable 这样的代码中&#xff0c;他的方法都是使用 sync…

dify 部署后docker 配置文件修改

1&#xff1a;修改 复制 ./dify/docker/.env.example ./dify/docker/.env 添加一下内容 # 启用自定义模型 CUSTOM_MODEL_ENABLEDtrue# 将OLLAMA_API_BASE_URL 改为宿主机的物理ip OLLAMA_API_BASE_URLhttp://192.168.72.8:11434# vllm 的 OPENAI的兼容 API 地址 CUSTOM_MODE…

数据结构——排序(万字解说)初阶数据结构完

目录 1.排序 2.实现常见的排序算法 2.1 直接插入排序 ​编辑 2.2 希尔排序 2.3 直接选择排序 2.4 堆排序 2.5 冒泡排序 2.6 快速排序 2.6.1 递归版本 2.6.1.1 hoare版本 2.6.1.2 挖坑法 2.6.1.3 lomuto前后指针 2.6.1.4 时间复杂度 2.6.2 非递归版本 2.7 归并排序…

快速入门深度学习系列(3)----神经网络

本文只针对图进行解释重要内容 这就是入门所需要掌握的大部分内容 对于不懂的名词或概念 你可以及时去查 对于层数 标在上面 对于该层的第几个元素 标在下面 输入层算作第0层 对于第一层的w b 参数 维度如下w:4*3 b:4*1 这个叫做神经元 比如对于第一层的神经元 这里说的很…

在线工具源码_字典查询_汉语词典_成语查询_择吉黄历等255个工具数百万数据 养站神器,安装教程

在线工具源码_字典查询_汉语词典_成语查询_择吉黄历等255个工具数百万数据 养站神器&#xff0c;安装教程 资源宝分享&#xff1a;https://www.httple.net/154301.html 一次性打包涵盖200个常用工具&#xff01;无论是日常的图片处理、文件格式转换&#xff0c;还是实用的时间…

Linux 阻塞和非阻塞 I/O 简明指南

目录 声明 1. 阻塞和非阻塞简介 2. 等待队列 2.1 等待队列头 2.2 等待队列项 2.3 将队列项添加/移除等待队列头 2.4 等待唤醒 2.5 等待事件 3. 轮询 3.1 select函数 3.2 poll函数 3.3 epoll函数 4. Linux 驱动下的 poll 操作函数 声明 本博客所记录的关于正点原子…

Java开发经验——阿里巴巴编码规范经验总结2

摘要 这篇文章是关于Java开发中阿里巴巴编码规范的经验总结。它强调了避免使用Apache BeanUtils进行属性复制&#xff0c;因为它效率低下且类型转换不安全。推荐使用Spring BeanUtils、Hutool BeanUtil、MapStruct或手动赋值等替代方案。文章还指出不应在视图模板中加入复杂逻…

机器人手臂“听不懂“指令?Ethercat转PROFINET网关妙解通信僵局

机器人手臂"听不懂"指令&#xff1f;Ethercat转PROFINET网关妙解产线通信僵局 协作机器人&#xff08;如KUKA iiWA&#xff09;使用EtherCAT控制&#xff0c;与Profinet主站&#xff08;如西门子840D CNC&#xff09;同步动作。 客户反馈&#xff1a;基于Profinet…

深度学习 CNN

CNN 简介 什么是 CNN&#xff1f; 卷积神经网络&#xff08;Convolutional Neural Network&#xff09;是专为处理网格数据&#xff08;如图像&#xff09;设计的神经网络。核心组件&#xff1a; 卷积层 &#xff1a;提取局部特征&#xff08;如边缘、纹理&#xff09;通过卷…

MySQL索引原理以及SQL优化(二)

目录 1. 索引与约束 1.1 索引是什么 1.2 索引的目的 1.3 索引分类 1.3.1 数据结构 1.3.2 物理存储 1.3.3 列属性 1.3.4 列的个数 1.4 主键的选择 1.5 索引使用场景 1.6 索引的底层实现 1.6.1 索引存储 1.6.2 页 1.6.3 B 树 1.6.4 B 树层高问题 1.6.5 自增 id 1.7 innod…

MATLAB中矩阵和数组的区别

文章目录 前言环境配置1. 数据结构本质2. 运算规则&#xff08;1&#xff09;基本运算&#xff08;2&#xff09;特殊运算 3. 函数与操作4. 高维支持5. 创建方式 前言 在 MATLAB 中&#xff0c;矩阵&#xff08;Matrix&#xff09; 和 数组&#xff08;Array&#xff09; 的概…

Desfire Ev1\Ev2\Ev3卡DES\3K3DES\AES加解密读写C#示例源码

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.1d292c1bYhsS9c&ftt&id917152255720 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using S…