【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.mzph.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写个小的软件,试着找个三方上架一下应用市场玩玩。毕竟不可能一直在简历上挂一…