介绍几种常见平台下的内存泄露检测工具 Visual C++ 在 Windows 系统下查找和修复内存泄露 使用方法 在Microsoft Visual C++中,其调试库内建了对内存泄漏的支持; 对于下面这个代码: #include <iostream> int main(){ int* p0 = new int{}; int* p1 = new int{};
前文简单介绍了Linux中的信号产生和信号捕捉的初步认识,这一篇文章我们将进一步了解Linux信号中的阻塞信号,并深入理解信号捕捉的具体过程。 阻塞信号 概念解释 在介绍阻塞信号之前,我们需要了解一些信号相关的概念: 实际执行信号的处理动作称为信号递达(Delivery) 信号从产生带递达之间的状态,称为信号未决(Pending) 进程可以选择阻塞(Block)某个信号 被阻塞的信号产生时将保持
在Linux系统中,信号是一种用于进程间通信和进程控制的机制,它允许系统内核和用户进程对其他进程进行通知、干预和控制。信号可以被用于各种用途,例如终止进程、暂停进程、捕捉异常以及处理用户自定义事件。 为了更好地理解进程信号,我们将从以下几个方面进行探讨: 信号的基本概念:什么是信号,信号的种类,以及信号的特性。 信号的发送与处理:如何向进程发送信号,进程如何捕捉和处理信号。 常用信号:例如 SI
引入 上一篇文章介绍了 Linux 中通过pipe创建匿名管道,并实现父子进程间通信的功能;当时我就提到了 Linux 中的另一种管道通信方式——命名管道,下面就来详细介绍一下; 命名管道 什么是命名管道 命名管道(Named Pipe),也叫FIFO(First In First Out),是一种用于进程间通信(IPC)的机制。与匿名管道不同,命名管道是存在于文件系统中的特殊文件,具有持久性,可
引入 之前我们介绍了多进程以及创建进程的函数forki,下面我们将继续深入,讨论一下多进程间的通信问题; pipe 管道 谈论多进程通信,就离不开pipe(管道),这是一个系统调用,用于在 UNIX 和类 UNIX 系统(如 Linux)上创建一个管道(pipe),实现进程间通信。它创建了一个双向的通信通道,允许一个进程向另一个进程发送数据。管道是单向的,即数据只能沿一个方向流动:从读端读取数据,
重定向 即通过重定向操作符,使得输入输出位置发生更改的功能,称为重定向; 实现之前 为了简化实现过程,我们采用之前所完成的自制shell来实现重定向;自制shell在此 下面分别介绍一下三个常见的重定向符号: 输入重定向(<) <:用于将文件的内容作为命令的标准输入。 command < filename 功能:将filename的内容作为command的标准输入来处理。
替换原理 fork创建子进程后执行的是和父进程相同的程序(但又可能执行不同的代码分支),如果想让子进程执行不同的程序,可以通过exec函数启动另一程序并替换执行; 当调用exec函数后,该进程的用户空间代码和数据完全被新程序替换; 调用exec函数并不创建新进程,所以调用前后的进程 id 不改变; 替换函数 execl(执行文件名 + 变长数) 格式:int execl(const char*
STL源码库中,空间配置器是内存分配的基石,最近在研究STL源码库时也是花了较长时间理解,所以这里记录一下我的学习历程(在这篇文章中,先实现第一级空间配置器),根据自己的理解实现了一份空间配置器,随后再通过这个配置器实现一个简单的vector容器;STL的第一级空间配置器空间配置器首先介绍一下什么是空间配置器——所谓空间配置器,就是STL库内进行内存分配的工具,一般分为两种类型:第一级空间配置器:
当我们实现一个简单的SmartPtr类时,需要考虑当对象为空指针的情况,此时对其的条件判断,如:SmartPtr<int> smt_ptr; if(smt_ptr == 0){} if(smt_ptr){} ...这些操作均会导致错误,这时我们可以对void*进行重载,使其返回空指针,便可以解决之前的问题:operator void*() const{ return nullptr;
——《深度探索C++对象模型》Default Constructor 的构造操作当我们没有显式的声明一个构造函数时,编译器会自动帮我们生成;但是这个构造函数的作用极其有限,比如下面这个例子:class Base{ public: int _val; }; int main(){ Base b; std::cout << b._val << std::endl;
当一个派生类由多个虚基类继承而来,其内部的虚函数表布局是怎么样的?以及当派生类中也存在虚函数时,其存储的位置在哪里?我们可以通过如下代码获取派生类中的虚函数表的具体布局:#include <iostream> class Base { public: virtual void vfunc1() { std::cout << "In Base vfunc1()" &l
#include <iostream> class MyClass { public: MyClass() { std::cout << "Constructor called" << std::endl; } MyClass(const MyClass& other) { std::cout &
new operatorC++中,可以使用new在堆空间上申请内存,使用delete进行释放操作:class Base { public: Base() { std::cout << "constructor is called." << std::endl; } ~Base() { std::cout << "destructor is call
——《C++ Concurrency In Action》等待事件或条件在并发线程中,当某个线程等待另一线程完成时,该线程会持续的检查共享的数据标志的状态(类似于互斥量的释放),以确定等待线程是否完成了任务,而且当互斥量上锁时,数据访问被禁止,这就会导致在等待过程中消耗时间成本;同时对状态的检查也会消耗系统资源;我们可以在等待期间使用std::this_thread::sleep_for()进行周
可调用对象函数对象的支持函数指针函数对象(仿函数)lambda表达式这里的函数指针也可以是函数名,其在传入参数时退化成函数指针类型:#include <iostream> using func_ptr = void(*)(); // 声明函数指针类型 class Func_object { public: func_ptr ptr1; func_ptr operator()()
——《C++Templates》之前我们所述的模板,其用途之一就是用于C++的编译期编程,这也是C++语言的一大特性之一,下面就简单介绍一下C++的模板元编程;模板元编程模板不同于动态语言,其实例化过程发生于编译期,而动态语言则是在运行期处理泛型的;由此,我们可以在编译期自定义一种“原始的编程语言”,并直接在编译期完成结果的计算;下面演示一个在编译期实现质数判断的例子(书中给出的实例):#incl
——《C++Templates》完美转发(Perfect Forwarding)std::forward完美转发(perfect forwarding)是指在函数模板中通过保留传递给模板的参数的值类别(左值或右值)来转发它们,从而将参数完整地传递给另一个函数。完美转发的主要目的是在不丢失参数的值类别的情况下,将参数传递给其他函数,以保持传递参数的原始形式;其一般和移动语义相结合,用于右值类型的传递
——《C++Templates》什么是变参模板模板参数可以定义为接收无限数量的模板参数,具备这种能力的模板称为变参模板;变参模板示例#include <iostream> void print() { } template<typename T, typename... Args> void print(T first_element, Args... args) {
非类型类模板参数在模板编程中,除了将类型作为模板的参数外,还可以将非类型的模板参数作为参数传递:template<typename T, int val> class example { public: void show() { std::cout << "val = " << val << std::endl; } };将int类型的va
关键字typename和class对于声明一个模板类时,常见两个关键字——typename、class:template<class T> class Example; template<typename T> class Example;两种声明方式等价,但这仅限于声明template模板参数,在某些情况下,二者并不等价;typename用于类型的显式声明例如下面的例子:
藉由Non-Virtual Interface手法实现Template Method模式该模式的主要思想就是通过一个non-virtual函数调用纯虚函数,而被调用的纯虚函数一般都声明为private私有属性,阻止对其的直接访问,只允许派生类对其进行重写;实例如下:#include <iostream> #include <string> class Base { pub
选自《Effective C++》条款34继承这里简单的介绍一下什么是继承:继承是面向对象中的一个重要概念,它允许一个类继承另一个类的属性与方法,被继承的类称为父类或基类,对应的称为子类或派生类。接口继承和实现继承对于类的继承中的成员函数继承,我们不难发现其分为两种形式:函数接口继承和函数实现继承,两者的具体使用场景也不同;成员函数的接口总是会被继承对于public继承,原文认为这是一种is-a关
C++11简介在2003年C++标准委员会曾经提交了一份技术勘误表(简称TC1),使得C++03这个名字已经取代了 C++98称为C++11之前的最新C++标准名称。不过由于TC1主要是对C++98标准中的漏洞进行修复,语言的核心部分则没 有改动,因此人们习惯性的把两个标准合并称为C++98/03标准。从C++0x到C++11,C++标准10年磨一剑, 第二个真正意义上的标准珊珊来迟。相比于C++
C++异常概念异常是一种处理错误的方式,当一个函数发现自己无法处理的错误时就可以抛出异常,让函数的直接或间接的调用者处理这个错误。C++的异常主要有三个关键字:throw:当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。catch:在您想要处理问题的地方,通过异常处理程序捕获异常;catch 关键字用于捕获异常,可以有多个catch进行捕获。try:try 块中的代码标
多态的概念多态(Polymorphism)是面向对象编程中的一个重要概念,它允许同一类型的对象在不同的上下文中表现出不同的行为。多态性有两种主要形式:编译时多态(静态多态性)和运行时多态(动态多态性)。编译时多态可以看成是函数重载和运算符重载,之前的文章已经涉及过,不再赘述;所以,下面所提到的多态,都指的是运行时多态。多态的定义及实现多态的构成条件 多态是在不同继承关系的类对象,去调用同一函数,产
类的继承的概念及定义继承的概念类的继承即对类设计层次的复用,可以在保持原有类结构的基础上对类进行进一步拓展,完成类的继承后,原有的类称为基类/父类,继承的类称为派生类/子类如何定义一个继承类定义一个继承类的基本语法如下class Person {}; class Student :public Person { };这里的Person是基类,派生类Student继承了基类Person类;这里的p
什么是string类string类是C++STL中提供的字符串类,用于高效的处理字符串类型数据,其包含在头文件<string>中string的简单实现构造函数和析构函数为了防止与STL中的string类冲突(当我们引入命名空间std时),我们将模拟string置于命名空间namespace X中,如下所示namespace X { class string { public:
什么是模板模板分为类模板和函数模板,关键字为template,基本的声明形式如下:template<class T>; //也可以写成这样 template<typename T>class 和 typename 在声明模板参数时的用法是相似的,一般情况下可以互换但在成员模板内部访问嵌套类型时,需要使用 typename。下面举一个例子加以理解:template <c
智能指针C++中的智能指针分为4类,分别是:共享指针(std:shared_ptr)独占指针(std::unique_ptr)auto_ptrweak_ptr其中,auto_ptr已被C++11标准摒弃,C++17标准已经不可用。智能指针的出现,能够很好的解决原始指针因为忘记释放内存而导致的一系列问题,或是因为删除不彻底而形成的空悬指针问题。接下来,我将分别介绍不同的智能指针及其具体的使用方法sh
仿函数和lambda表达式仿函数仿函数,就是一种类类型,通过重载调用运算符"()"来实现像函数一样的调用功能,所以称之为仿函数#include<iostream> class Add { private: int a; int b; public: int operator()(int a, int b) { //operator就是对调用运算符进行重载 return a +
Copyright © 2005-2024 51CTO.COM 版权所有 京ICP证060544号