,可以正常走到监听 socket 的 accept 函数,之后下一轮循环走到 epollPollSelectDectector 时就崩溃了,且通过崩溃的调用堆栈最底层只能看到这个函数,epollPollSelectDectector...的源码与二进制文件不匹配误报了错误堆栈这两个原因。...m_sessionMutex; }; 既然是对象重复释放问题,那么我们在这几个自定义类的构造函数和析构函数中加上日志,并打印当前对象 this 指针观察一下,看看各个对象的构造和析构是否成对匹配。...的成员变量智能指针),HttpSession 即使不使用 HttpConnection 对象,在断开连接时,HttpSession 析构会触发其成员变量 HttpConnection 对象的析构,而此时...(clientID, pSession); } } 但是,这样的代码还是无法编译,所以现在传递给 HttpSession 的构造函数中第一个实参是右值了,但是对不起,等实际传到 HttpSession
它接受一些参数,如线程的入口函数、线程的堆栈大小等,可以创建一个新的线程并返回线程句柄。开发者可以使用该句柄控制该线程的运行状态。...lpThreadId:指向一个DWORD变量的指针,表示返回的线程ID号。可以为NULL。 CreateThread 函数将创建一个新的线程,并返回线程句柄。...它也接受一些参数,如线程的入口函数、线程的堆栈大小等,与CreateThread不同的是,_beginthreadex函数返回的是线程的ID,而不是线程句柄。...stack_size:指定线程的堆栈大小,以字节为单位。如果stack_size为0,则使用默认的堆栈大小。 start_address:线程函数的入口点。 arglist:传递给线程函数的参数。...与CreateThread不同的是,_beginthreadex函数接受传递给线程函数的参数放在arglist中,方便传递多个参数。线程使用完需要调用_endthreadex函数来关闭线程。
它接受一些参数,如线程的入口函数、线程的堆栈大小等,可以创建一个新的线程并返回线程句柄。开发者可以使用该句柄控制该线程的运行状态。...lpThreadId:指向一个DWORD变量的指针,表示返回的线程ID号。可以为NULL。CreateThread 函数将创建一个新的线程,并返回线程句柄。...它也接受一些参数,如线程的入口函数、线程的堆栈大小等,与CreateThread不同的是,_beginthreadex函数返回的是线程的ID,而不是线程句柄。...stack_size:指定线程的堆栈大小,以字节为单位。如果stack_size为0,则使用默认的堆栈大小。start_address:线程函数的入口点。arglist:传递给线程函数的参数。...与CreateThread不同的是,_beginthreadex函数接受传递给线程函数的参数放在arglist中,方便传递多个参数。线程使用完需要调用_endthreadex函数来关闭线程。
(即线程将执行的代码) _func(func), _status(TSTATUS::NEW), _joinable(true) 初始化列表 _func(func): 将传入的 func 参数赋值给类的成员变量...void * 其中,start_routine 参数是一个函数指针,要求该函数的签名是:void* (*start_routine)(void*),即它必须是一个接受 void* 参数并返回 void...std::shared_ptr 是一种智能指针,能够确保其管理的对象在没有任何 shared_ptr 指向它时自动释放资源,这样就不需要显式地调用 delete 来释放内存。...如果你直接使用裸指针或 std::unique_ptr,则无法保证线程之间对对象的正确共享,特别是在涉及线程管理的复杂场景时 例如,如果每个线程使用 std::shared_ptr 来引用同一个线程对象...线程函数的逻辑无法灵活地接收不同类型的数据。 修改后的代码:Thread 类被模板化,允许线程类接受任意类型的参数 T。通过模板类型参数 T,你可以创建一个接受任意类型数据的线程。
所以,在 RAII 的指导下,我们应该使用类来管理资源,将资源和对象的生命周期绑定 智能指针(std::shared_ptr 和 std::unique_ptr)即 RAII 最具代表的实现,使用智能指针...C/C++的函数参数是通过压入堆栈的方式来给函数传参数的,所以最后压入的参数总是能够被函数找到,因为它就在堆栈指针的上方。...为什么拷贝构造函数必须传引用不能传值 拷贝构造函数的作用就是用来复制对象的,在使用这个对象的实例来初始化这个对象的一个新的实例。...this 指针调用成员变量时,堆栈会发生什么变化 当在类的非静态成员函数访问类的非静态成员时,编译器会自动将对象的地址传给作为隐含参数传递给函数,这个隐含参数就是 this 指针。...weak_ptr weak_ptr 是一种不控制所指向对象生存期的智能指针,它指向由一个 shared_ptr 管理的对象,将一个 weak_ptr 绑定到一个 shared_ptr 不会改变引用计数
③如果参数个数确定,this指针通过ecx传递给被调用者,如果参数不确定,this指针在所有参数被压栈后压入堆栈。 ④对参数个数不定的,调用者清理堆栈,否则函数自己清理堆栈。...首先应该明确的是指针和引用在底层的实现是相同的,之所以叫this指针,是因为最开始将C++称作带类的C,而引用则是在C++1.0版才加入使用的,因此叫做this指针。...但是,既使是虚函数,如果编译器能明确知道调用的是哪个函数,编译器就不会通过函数表中的指针来间接调用,而是会直接调用该函数。 this指针如何传递给类中函数的?绑定?...还是在函数参数的首参数就是this指针? 大多数编译器通过ecx寄存器传递this指针。事实上,这也是一个潜规则。一般来说,不同编译器都会遵从一致的传参规则,否则不同编译器产生的obj就无法匹配了。...类在实例化时,只分配类中的变量空间,并没有为函数分配空间。自从类的函数定义完成后,它就在那儿,不会跑的。 为什么this指针不能再静态函数中使用?
这种方式在某些情况下可能导致问题,例如,当回调执行时,原始变量已经失效(例如,原始变量是栈上的局部变量,而回调在该变量离开作用域后执行)。 按值捕获是将外部变量的值复制到Lambda表达式的闭包中。...这会导致程序偶现闪退,也可能导致数值异常,最终表现为业务逻辑异常,因为回调函数试图访问一个已经失效的栈变量。 修改的方式是,将 st_or_code 变量改为按值捕获。...这里,base::AsWeakPtr(this) 将this指针转换为弱引用,并将其传递给Lambda表达式。..._WrapWeakCallback 函数接受一个回调函数(callback)和一个弱引用(weakptr)。它将创建一个新的回调函数,该回调函数在调用之前会检查弱引用的有效性。...按引用捕获 将外部变量的引用存储在Lambda表达式的闭包中,使得Lambda表达式在执行时直接访问的是原始变量。
只要有可能就推迟变量定义 27. 将强制转型减到最少 28. 避免返回对象内部构件的“句柄” 29. 争取异常安全(exception-safe)的代码 30....两个通用的 RAII 是 tr1::shared_ptr 和 auto_ptr。tr1::shared_ptr 通常是更好的选择,因为它的拷贝时的行为是符合直觉的。...在一个独立的语句中将 new 出来的对象存入智能指针 用一个单独的语句创建 Widget 并将它存入一个智能指针,然后将这个智能指针传递给 processWidget: std::tr1::shared_ptr...将数据成员声明为 private 声明数据成员为 private。它为客户提供了访问数据的语法层上的一致,提供条分缕析的访问控制,允许不变量被强制,而且为类的作者提供了实现上的弹性。...只要有可能就推迟变量定义 只要有可能就推迟变量定义。这样可以增加程序的清晰度并提高程序的性能。 27.
(C++终于支持匿名函数了) 标准形式是 外部变量->返回值 {函数体} 当然“->返回值”可以省去,这时候会有返回值类型推导 对于引用的外部变量的形式,见下表(参考维基百科的) capture description...[] 无任何外部变量 [x, &y] x以传值方式导入,y以引用方式导入 [&] 所有变量都以引用方式导入 [=] 所有变量都以传值方式导入 [&, x] 除x以传值方式导入外,其他变量以引用方式导入...其中std::shared_ptr是智能指针,一下是最简单的用法 std::shared_ptr a = std::shared_ptr(new int()), b = std...另外智能指针上还有个重要的东西叫std::weak_ptr,这是智能指针的一个监视器,内部不会改变引用技术,但是可以用于获取智能指针,当资源正常时lock函数会返回智能指针,当资源被释放了后会产生空指针...但是某些情况下我们需要返回自己的智能指针怎么办呢,又有个新玩意,std::enable_shared_from_this ,只要继承它,就有一个成员方法shared_from_this用于返回自身的智能指针
因为std的做不到全平台可用,UE4的智能指针可以无缝兼容UE4的容器,可以不要求保证线程安全,这样能带来更好的性能,允许赋值空指针,提供了一些UE4自己的辅助函数,而且UE4的性能更好(包括将函数inline...如果你看过stl的源码或用过std::shared_ptr,肯定知道创建指针的时候要尽可能用make_shared而不是直接使用构造函数,他们在内存的分配上有本质的差别。...TSharedFromThis 对应STL中的std::enable_shared_from_this,用法就像注释所说的,需要自己的类继承这个类,就可以自动将当前的对象进行引用计数管理,之后通过AsShared...因为只是一个变量,没赋值的时候并没有指向自己,所以需要找到赋值的地方: 可以看到只有在调用UpdateWeakReferenceInternal这个函数的时候,才会被参数传进来的SharedPtr初始化好...再看第二个函数MakeShared,他接收的参数是一堆可变的参数,看注释也说了,等价于std::make_shared,直接在一块内存上构造智能指针和对象本身,好处是对内存就非常友好,减少了一个内存碎片
下面举个例子说明一下shared_ptr: /*智能指针和空指针*/ //智能指针只能被智能指针赋值,不能用shared_ptr pq= new int; shared_ptr...使用shared_ptr需要include */ 如果将share_ptr定义为类的成员变量,那么此智能指针的retain引用会在该对象被释放的时候才释放。 ...[a,&b]传入变量a的值以及变量b的引用 3.[&]以引用的方式传入所有的变量 4.[=]以传值的方式传入所有的变量,值不可以被修改 5....[&,a]除了a用传值的方式,其他变量都已引用的方式传入 6....,静态函数和类的公有成员函数,前两者和lambda的用法一样,直接将函数名赋值给function对象即可(无法识别重载的函数),但类的成员函数需要使用bind来绑定: ClassA *obj =
答案是不会,虽然我们传给子线程看上去是引用传递,实际上是将val的值拷贝给了 函数参数 i,可以通过调试程序,查看各个变量的内存地址,就会发现 val 和 val_y内存地址相同,但是 i 的地址与val...传递类对象、智能指针作为线程参数 在线程中修改变量的值不会影响到主线程。 将类A的成员变量m_i改成mutable。...0; } 虽然传进去的是引用,但是线程中对m_i的值进行修改,不会影响到main函数中的a对象的m_i的值。...智能指针,想从一个堆栈到另一个堆栈,需要使用std::move() #include #include #include using namespace...注意是不是使用了std::ref()进行传参。 关注是不是主线程中的资源值拷贝方式给了子线程。
();//此时我们知道期望对象 fut没有指涉到由 std::async调用产生的共享状态,所以它的析构函数将表现为常规行为 //但是 std::packsgaed_task不能复制,将pt传递给...之后,会在内存中为 std::vector构造一个 x的副本 * ,这是第二次的构造,它的结果在 std::vector内创建了一个新的对象 (用来将 x复制到 std::vector中的构造函数,是移动构造函数..., * 因为作为右值引用的x,在复制之前被转换成了右值) * * 3,最后 push_back返回的那一时刻,tmp被析构,所有,这就需要调用一次std::string的析构函数 */ //因此,有没有办法将字符串字面量直接传递给步骤...* 1,构造一个 std::shared_ptr型别的临时对象,用来持有 从 “new Widget”返回的裸指针,该对象成为tmp * * 2,push_back会按引用方式接受...,那个Widget都发生了泄露 * * * @return int */ //正确的做法 //从 new Widget中获取指针并将其在独立语句中转交给资源管理对象,然后该对象作为右值传递给你最初想要向其传递
,这些型别包括 std::unique_ptr std::future和std::thread等 2,完美转发:使人们可以撰写接受任意实参的函数模板,并转发到其他函数,目标函数会接受到与转发函数所接受的完全相同的实参...得移动构造函数,因为移动构造函数只能接受非常量 std::string型别得右值引用作为形参 2,这个右值可以传递给复制构造函数,因为指涉到常量得左值引用允许绑定到一个常量右值型别得形参...//计算任意函数调用所花费的时长 //4, auto&& 型别的变量都是万能引用 //计算任意函数调用所花费的时长 auto timeFuncInvocation = [](auto&& func,...::string的构造函数来创建临时对象,一次std::string的 移动赋值运算符来移动 newName到 w.name,还有一次std::string的析构函数来销毁临时变量 解释3:扩展问题 一个形参可以重载...1,调用执行后,形参name被绑定到传入的 short型别的变量上 2, name被std::forward传递给 names的emplace成员函数 3, name又被转发给 std
extern "C"的作用 在函数前面添加 将C++风格的函数,编译为C风格、函数重载会无效 指针常量和常量指针的区别 指针常量:指针指向的数据不能被修改,但指针本身的值可以改变。...函数指针 函数指针是一种变量,其值为另一个函数的地址。函数指针允许你将函数作为参数传递给其他函数,或者存储函数的引用以便稍后调用。函数指针的定义包括了函数的原型(返回类型、函数名和参数列表)。...指针函数通常用于动态内存管理或返回特定类型的指针,而函数指针提供了一种灵活的方式来操作函数,允许你将函数作为参数传递或存储函数引用以便稍后调用。...智能指针 智能指针是一种具有自动资源管理功能的指针,如 std::unique_ptr, std::shared_ptr,std::weak_ptr能够自动管理内存生命周期。...堆栈溢出 堆栈溢出一般是什么原因导致的堆栈溢出通常是由以下几种原因导致的: 函数调用层次太深:在函数递归调用时,每次调用都会在栈中保存函数调用时的现场和产生的变量。
,而每个引用计数最终都会变为零,从而导致 *pw 被析构两次,第二次析构就会引发未定义行为 //因此可以得到两个结论: /** 1,尽可能避免将裸指针传递给一个 std::shared_ptr的构造函数...,替代手法是使用 std::make_shared,但是使用了自定义析构器,无法用std::make_shared 2,如果必须将一个裸指针传递给std::shared_ptr的构造函数,直接传递 new...new 表达式 std::shared_ptr spw22(spw11);//spw22使用的是和spw11同一个控制块 //问题2: //使用 裸指针变量作为 std::shared_ptr...删除 // 器的型别对 std::shared_ptr 的型别没有影响 // • 避免使用裸指针型别的变量来创建 std: : shared _ptr 指针 条款20:对于类似 std::shared_ptr...::make_unique , 利用C++11实现一个基础版本的 std::make_unique //将形参向待创建对象的构造函数作了一次完美转发,并返回一个指涉到该对象的智能指针 //这个形式的函数不支持数组和自定义析构器
、驱动虚拟文件系统(vfs) 内核空间是受保护的,用户不能对内核空间读写,否则会出现段错误 环境变量(env) PATH 命令行参数 char *agrv[] 栈区⬇️ 函数的返回地址,返回值,参数,局部变量...后 没有delete/free掉 系统资源泄漏 --- 系统分配的资源,没有用指定的函数释放掉,导致系统资源的浪费,严重影响系统性能,如:socket,bitmap,handle 没有将父类的析构函数定义为虚函数...类,使用shared_from_this函数进行返回 注意事项: 不要将this指针作为返回值 要避免循环引用 不要再函数实参中创建shared_ptr,在调用函数之前先定义以及初始化它 不要用一个原始指针初始化多个...shmdt 分离共享内存 shmctl 控制共享内存 c++ STL内存优化 c++11新特性: 关键字和语法 auto关键字 编译器可以根据初始化来推导数据类型,不能用于函数传参和以及数组类型推导...inline 函数 函数体内的代码比较长,将导致内存消耗代价; 函数体内有循环,函数执行时间要比函数调用开销大; 另外类的构造与析构函数不要写成内联函数。
你可以使用 std::move 函数将左值转换为右值引用。...当你使用std::move函数将一个unique_ptr对象转化为右值引用并将其传递给另一个unique_ptr对象来初始化时,就会调用这个构造函数 unique_ptr& operator=(unique_ptr...,并且使用new int动态分配内存来存储一个int类型的对象 第四行代码创建另一个unique_ptr对象p2,并且使用std::move()将p1转化为右值引用并传递给p2的移动构造函数,...shared_ptr是标准库的一个智能指针类 shared_ptr pa(new A());这行代码,使用一个new A() 创建了一个新的A类型的对象,并将其地址作为参数传递给shared_ptr...的构造函数来创建一个新的shared_ptr对象,然后这个新创建的shared_ptr对象被赋值给变量pa 这也就是说变量pa是一个shared_ptr类型的对象,它指向一个新创建的
⽽是将错误代码通过返回值返回 pthreads同样也提供了线程内的errno变量,以⽀持其它使⽤errno的代码。...在ps -aL 得到的线程ID,有一个线程ID和进程ID相同,这个线程就是主线程,主线程的栈在虚拟地址空间的栈上,而其他线程的栈在是在共享区(堆栈之间),因为pthread系列函数都是pthread库提供给我们的...,因为当其它线程得到这个返回指针时线程函数已经退出了。...,后者指向线程的返回值 返回值:成功返回0;失败返回错误码 调⽤该函数的线程将挂起等待,直到id为thread的线程终⽌。...// 8,传参问题: 传递参数,可以是变量,数字,对象!
领取专属 10元无门槛券
手把手带您无忧上云