四川省广安建设局网站,男人和女人做性的网站,如何自己创建购物网站,苏州网站建设求职简历补充前序知识#xff1a;
1.CMakeLists.txt文件中#xff0c;如下图#xff0c;第一行生成的是静态库文件#xff08;我们前一讲所使用的#xff09;#xff0c;第二行是动态库文件。 静态库与动态库#xff1a;
静态库#xff08;Static Libraries#xff09;
定义…补充前序知识
1.CMakeLists.txt文件中如下图第一行生成的是静态库文件我们前一讲所使用的第二行是动态库文件。 静态库与动态库
静态库Static Libraries
定义 静态库是在编译链接阶段被链接到目标程序的库。这意味着库中的函数和数据会被直接嵌入到最终的可执行文件中。
何时使用
当你希望你的应用程序是一个独立的、不需要额外依赖的二进制文件时。在需要保证应用程序的稳定性和安全性的情况下避免外部动态库的版本冲突或缺失。
优点
可执行文件可以在没有额外库文件的情况下运行提高了部署的便捷性。减少了由于外部库文件缺失或版本不匹配导致的运行时错误。
缺点
生成的可执行文件较大因为包含了所有库的代码。不利于代码更新每次修改库代码都需要重新编译链接整个应用程序。资源消耗较大如果多个程序使用相同的静态库每个程序都会包含一份库的副本。
动态库Dynamic Libraries
定义 动态库是在程序运行时被加载的库。它们不会被直接嵌入到可执行文件中而是在运行时通过系统调用加载。
何时使用
当你希望你的应用程序能够利用系统上最新的库版本或者需要与多个不同版本的库兼容时。在开发大型系统或组件化软件时动态库可以提供更好的模块化和代码重用。
优点
可执行文件较小因为不会包含完整的库代码。多个应用程序可以共享同一个动态库节省了系统资源。动态库可以独立更新而不影响已经部署的程序。
缺点
需要确保目标系统上有正确的动态库版本否则程序可能无法运行。加载动态库会增加启动时间和运行时的复杂性。如果动态库的API改变可能需要更新使用该库的所有应用程序。
两者区别
静态库 当使用静态库时编译器和链接器会在链接阶段将静态库中的对象文件.o或.obj文件合并到最终的可执行文件中。这实际上意味着静态库的代码和数据会被包含在最终的可执行文件中就好像它们是原生代码的一部分一样。因此当可执行文件运行时它并不需要外部的库文件因为所有必要的代码都已经存在于可执行文件内部了。
动态库 相比之下动态库或共享库在链接阶段仅记录了一个引用而不是实际的代码和数据。当程序运行时操作系统会查找并加载这些动态库。程序通过动态链接器或加载器间接调用动态库中的函数。这意味着动态库的代码和数据存储在独立的文件中并且在运行时由操作系统动态地连接到正在运行的程序上。如果多个程序使用同一个动态库那么这个库只被加载一次从而节省了内存。 这种区分在概念上与“内联”和“函数调用”有点类似但实际上是关于代码如何在编译和链接阶段被处理以及在运行时如何被加载和执行的问题。静态库的行为更像是将函数“内联”到每个调用它的位置而动态库则保持函数调用的独立性即调用者和实现者分离直到运行时才将两者结合在一起。
——————————————————————————————————
IDE全称为Integrated Development Environment即集成开发环境。它是一种软件应用旨在提供一个统一的界面使程序员能够更方便地编写、测试和调试代码。IDE通常包括代码编辑器、编译器、调试器以及其他工具如版本控制系统、图形用户界面设计工具等。 流行的IDE包括Visual Studio针对C、C#等、Eclipse针对Java、PyCharm针对Python、IntelliJ IDEA针对Java和Kotlin、Xcode针对Swift和Objective-C等。 在这里可以使用kdevelop并自行安装。它支持CMake和C。 在kdevelop中运行程序
1.加载程序按理说只需文件夹里有一个配置文件即可下图中文件夹里有多余文件
注意在KDevelop中当你选择Project - Open/Import Project路径后应该选择一个包含CMakeLists.txt文件的文件夹而无法选择单个的.txt文件。这是因为KDevelop是根据CMakeLists.txt文件来识别和管理项目的。当你选择包含CMakeLists.txt的文件夹时KDevelop会自动识别出这是一个CMake项目并根据其中的配置来设置项目环境。 2.注意将功能选项卡切换至project选项并检查是否成功导入 (如果第一步文件夹里只有配置文件的话应该只显示红框中的部分) 3.Debug比如我输入如下图的“不合法”语句依旧可以通过编译int *p0*p1
PS下面代码问题为: 这段代码的问题在于它试图访问一个未初始化的指针所指向的内存位置并对其进行写操作。
int *p 0; 这一行声明了一个整型指针p并将其初始化为0。在C和C中0或等价的NULL通常用来表示一个空指针即这个指针不指向任何有效的内存地址。
*p 1; 这一行尝试通过指针p去访问某个内存位置并将1赋值给该位置。然而由于p被初始化为0这意味着它实际上并不指向任何合法的内存区域。当你尝试解引用一个空指针或未正确初始化的指针时程序的行为是未定义的Undefined Behavior这意味着程序可能会崩溃或者表现出其他不可预测的行为甚至可能看起来正常工作但这通常是一种误导。 通俗地说你可以想象指针就像一把钥匙它允许你打开并访问内存中的某个“房间”。当你将指针初始化为0时你实际上没有一把可以打开任何房间的钥匙。然后当你尝试使用这把“不存在”的钥匙去打开一个房间并放置一些东西例如1时你就闯入了一个未知的空间这可能导致各种问题包括但不限于程序崩溃。 为了避免这类问题你应该始终确保你的指针被正确初始化并且在解引用之前它们确实指向一个合法的内存地址。例如我们可能需要分配内存使用new或malloc或让指针指向一个已存在的变量。
int *p (int*)malloc(sizeof(int)); // 为整数分配内存并将地址赋给指针p
if (p ! NULL) { // 检查内存分配是否成功*p 1; // 现在可以将值1安全地赋给p所指向的内存位置
}
——————————————————————
如下图所示存在有问题的语句但是却通过了编译。编译需要点击Build键 但是当我们在运行时就会出现问题。 如图程序中的报错就代表了程序已经崩溃了当出现这种报错时由于它没有显示哪行出现了何种问题的提示我们就需要对程序进行debug如放断点
这时我们需要在项目的CMakeLists.txt文件中直接设置CMAKE_BUILD_TYPE变量。格式如下
set(CMAKE_BUILD_TYPE Debug)
将这行代码放在CMakeLists.txt文件的开始部分可以确保整个项目以Debug模式构建。
现在的配置文件整体如下 4.在编辑完配置文件后点击Build编译随后可以在文件中设置断点。注意要如下图设置打开边框选项易添加断点。 随后选择对应行右键添加断点即可。 5.随后要使程序进入该断点首先需要告诉它我想执行哪个程序配置文件中有多个可执行文件 Configure Launches允许你为你的项目设置不同的运行配置。这些配置定义了如何启动和运行你的程序包括指定可执行文件、命令行参数以及执行环境等。当想要运行或调试你的程序时需要告诉KDevelop如何启动它。这就是Configure Launches发挥作用的地方。 随后操作如图所示。 6.点击Debug随后程序就会停在断点处。点击红框处便会显示step out、step over、step into了 若显示当前配置不支持debug需要查看是否选择正确的执行文件如下图 调试示意图当从第八行继续step over后原本p为0并弹出错误提示SIGSEGV。 SIGSEGV错误全称为Segmentation Fault是一种在Unix-like操作系统中常见的程序错误信号。它表示程序试图访问其没有权限访问的内存区域或者访问的内存地址不存在。
引起SIGSEGV错误的原因可能包括
野指针访问已经释放或未初始化的指针。空指针解引用试图访问一个值为NULL的指针所指向的内存。数组越界访问数组时超出了其边界。非法内存访问试图写入只读内存区域。内存泄漏程序中存在内存泄漏导致内存不足或分配错误。指针操作不当例如指针越界等。使用未映射到进程内存空间的指针这可能意味着使用了错误的指针值。栈溢出函数调用层次过深超过了栈的最大容量。并发问题在多线程环境中不当的同步机制可能导致内存访问冲突。硬件问题极少数情况下硬件故障也可能导致SIGSEGV错误。 7.点击Frame Stack就可以看到具体哪里出现错误了 8.修复错误后可以点击Build重新编译或点击Execute运行看看是否正常运行。