c++,标准库std中全局函数 _Destroy_in_place(...)的分析

文章探讨了C++中一个函数如何处理指针类型的参数,发现即使指针类型没有析构函数,该函数仍会调用,但实际操作只是直接返回,没有执行任何实际代码。这在STL源码中的使用提供了实例。

(1)该函数的定义和位置如下:
在这里插入图片描述

可见,传入形参为某种类型的引用,该函数会执行形参的析构函数,还可以有效解决数组的连续析构。很强大的函数。
(2)疑问是,若形参是指针类型,该函数怎么执行,指针类型是没有析构函数的。
(3)举例,如下代码和实验结果:
在这里插入图片描述
可见,当该函数的形参是指针类型,没有析构和构造函数,该函数不执行具体的内容,什么也不做。
(4)我们可以以汇编代码跟踪一下,上面代码的反汇编代码如下:
在这里插入图片描述
如图,开始执行第22行代码,按F11 继续进入这个全局函数得汇编代码:
在这里插入图片描述
可见,当形参类型是指针时,该函数什么也没做。或者说指针类型是c++内置类型,c++编译器给指针类型规定的构造和析构函数中,就是没有任何代码,空函数体的。实际看汇编代码,根本就没有跳转,比如转至指针的析构函数执行。直接就ret返回了。这个奇怪现象,有别于真正的数据类型。也是本文探讨验证的初衷。以更多的了解该函数。
(5)该函数在vs2019上阅读STL源码时,频繁出现。有些数据结构里有指针类型的成员。STL总对指针调用_Destroy_in_place(…)。如图,举例是在单向链表forward_list 的源码中,在函数clear() 中。
在这里插入图片描述
在这里插入图片描述
如此,就解开了对指针应用该函数的疑惑,相当于什么也没做。谢谢阅读

你搞错了,源码如下 /****************************************************************************** * Copyright (c) 2025 MeiG Smart Co.Ltd. All Rights Reserved. * * This program is the confidential and proprietary information of MeiG * Smart Co.Ltd. ("Confidential Information"). You shall not disclose such * Confidential Information and shall use it only in accordance with the terms * of the license agreement you entered into with MeiG Smart Co.Ltd. * * Filename: volcano_pm_agent.cpp * * Description: * Meig low power management module. * Notes: * This code handles low power management functions including wake locks * and auto-sleep control. * * Version: 1.0 * Date: 2025-07-21 * Author: dumolin * * 1.0 2025-07-21 dumolin First version ******************************************************************************/ #define __LOG_TAG__ "VolcanoPm" #include <memory> #include <volcano_priv.hpp> #include <volcano_pm_config.h> #include <volcano_pm.hpp> #include <volcano_gpio_config.h> #include <cstdlib> #include <unistd.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/socket.h> #include <sys/un.h> #include "volcano_pm_config.h" namespace volcano { namespace api { namespace pm { using namespace volcano::api::pm; struct Impl : public volcano::api::pm::Iface { //static volcano_lpm_handler_t volcano_lpm_func; Impl(std::shared_ptr<volcano::fmk::msg::Iface> msg) : msg_(msg){}; std::shared_ptr<volcano::fmk::msg::Iface> msg_; std::unordered_map<int, std::vector<void*>> cb_list_; void volcano_pm_active_cb(const nlohmann::json &msg) { // 1. 检查顶层字段是否存在(避免直接调用.at()抛出异常) if (!msg.contains("type") || !msg.contains("msg")) { VOLCANO_LOGE("Invalid JSON format: missing 'type' or 'msg' key"); return; } try { // 2. 安全提取字段(使用value()或get()避免异常) int type_int = msg.value("type", -1); // 默认值-1表示无效类型 if (type_int < 0 || type_int >= 2) { VOLCANO_LOGE("Invalid callback type: %d", type_int); return; } const auto& msg_data = msg.at("msg"); // 已知msg存在,直接使用at() auto it = cb_list_.find(static_cast<int>(type_int)); if (it == cb_list_.end()) { VOLCANO_LOGW("No callback registered for type: %d", type_int); return; } // 3. 遍历回调列表 for (void* cb : it->second) { try { auto type = static_cast<int>(type_int); switch (type) { case 1: { // 4. 检查嵌套字段是否存在 if (!msg_data.contains("lpm_edge")) { VOLCANO_LOGE("EINT1: missing required fields in 'msg'"); break; } int lpm_edge = msg_data.at("lpm_edge"); auto eint1_callback = reinterpret_cast<volcano_lpm_handler_t>(cb); eint1_callback( static_cast<VOLCANO_LPM_EDGE_E>(lpm_edge)); break; } default: VOLCANO_LOGE("Unknown callback type: %d", type_int); break; } } catch (const std::exception& e) { VOLCANO_LOGE("Callback execution failed: %s", e.what()); } } } catch (const nlohmann::json::exception& e) { // 5. 捕获JSON专属异常(如类型不匹配) VOLCANO_LOGE("JSON parsing error: %s", e.what()); } catch (const std::exception& e) { VOLCANO_LOGE("Unexpected error: %s", e.what()); } } int volcano_pm_reg_cb(const int cb_type, void* cb) { VOLCANO_LOGD("volcano_pm_reg_cb"); if (cb_type >= 1) { VOLCANO_LOGE("cb_type[%d] is invalid", static_cast<int>(cb_type)); return volcano::err::make(volcano::err::InvalidParam); } if (cb == nullptr) { VOLCANO_LOGE("cb is null"); return volcano::err::make(volcano::err::InvalidParam); } auto it = cb_list_.find(cb_type); if (it != cb_list_.end()) { it->second.push_back(cb); } else { cb_list_[cb_type] = {cb}; } return volcano::err::Ok; } int volcano_pm_unreg_cb(const int cb_type) { VOLCANO_LOGD("cb_type=%d", static_cast<int>(cb_type)); if (cb_type >= 1) { VOLCANO_LOGE("cb_type[%d] is invalid", static_cast<int>(cb_type)); return volcano::err::make(volcano::err::InvalidParam); } auto it = cb_list_.find(cb_type); if (it != cb_list_.end()) { it->second.clear(); cb_list_.erase(it); } return volcano::err::Ok; } int volcano_pm_subscribe_notice() { cb_list_.clear(); return msg_->subscribe_notice_j("volcano_pm", [this](const nlohmann::json &msg) { try { volcano_pm_active_cb(msg); } catch (const std::exception &e) { VOLCANO_LOGE("volcano_pm callback exception: %s", e.what()); } }); } int volcano_pm_unsubscribe_notice() { cb_list_.clear(); return msg_->unsubscribe_notice("volcano_pm"); } virtual int volcano_ms_slp_wakelock_create(const std::string name, int len) override { nlohmann::json req = { {"action", "volcano_ms_slp_wakelock_create"}, {"name", name}, {"len", len}, }; nlohmann::json reply; VOLCANO_LOGD("volcano_ms_slp_wakelock_create"); int err = msg_->request_j("volcano_pm", req, reply); if (err != volcano::err::Ok) { return err; } try { return reply["ret"]; } catch (std::exception &e) { return volcano::err::make(volcano::err::InvalidReply); } } virtual int volcano_ms_slp_wakelock_lock(int fd) override { VOLCANO_LOGD("volcano_ms_slp_wakelock_lock reg"); nlohmann::json req = { {"action", "volcano_ms_slp_wakelock_lock"}, {"fd", fd}, }; nlohmann::json reply; int err = msg_->request_j("volcano_pm", req, reply); if (err != volcano::err::Ok) { return err; } try { return reply["ret"]; } catch (std::exception &e) { return volcano::err::make(volcano::err::InvalidReply); } } virtual int volcano_ms_slp_wakelock_unlock(int fd) override { VOLCANO_LOGD("volcano_ms_slp_wakelock_unlock reg"); nlohmann::json req = { {"action", "volcano_ms_slp_wakelock_unlock"}, {"fd", fd}, }; nlohmann::json reply; int err = msg_->request_j("volcano_pm", req, reply); if (err != volcano::err::Ok) { return err; } try { return reply["ret"]; } catch (std::exception &e) { return volcano::err::make(volcano::err::InvalidReply); } } virtual int volcano_ms_slp_wakelock_destroy(int fd) override { VOLCANO_LOGD("volcano_ms_slp_wakelock_destroy reg"); nlohmann::json req = { {"action", "volcano_ms_slp_wakelock_destroy"}, {"fd", fd}, }; nlohmann::json reply; int err = msg_->request_j("volcano_pm", req, reply); if (err != volcano::err::Ok) { return err; } try { return reply["ret"]; } catch (std::exception &e) { return volcano::err::make(volcano::err::InvalidReply); } } virtual int volcano_ms_lpm_init(volcano_lpm_handler_t volcano_lpm_handler, volcano_lpm_cfg_t *volcano_lpm_cfg) override { VOLCANO_LOGD("volcano_ms_lpm_init reg"); volcano_pm_subscribe_notice(); if (volcano_lpm_handler) { volcano_pm_reg_cb(1, reinterpret_cast<void*>(volcano_lpm_handler)); } nlohmann::json req = { {"action", "volcano_ms_lpm_init"}, {"wakeup_gpio",volcano_lpm_cfg->wakeup_gpio}, {"active_low",volcano_lpm_cfg->active_low}, {"edge",volcano_lpm_cfg->edge}, }; nlohmann::json reply; int err = msg_->request_j("volcano_pm", req, reply); if (err != volcano::err::Ok) { return err; } try { return reply["ret"]; } catch (std::exception &e) { return volcano::err::make(volcano::err::InvalidReply); } } virtual int volcano_ms_autosleep_enable(int enable) override { VOLCANO_LOGD("volcano_ms_autosleep_enable reg"); nlohmann::json req = { {"action", "volcano_ms_autosleep_enable"}, {"enable", enable}, }; nlohmann::json reply; int err = msg_->request_j("volcano_pm", req, reply); if (err != volcano::err::Ok) { return err; } try { return reply["ret"]; } catch (std::exception &e) { return volcano::err::make(volcano::err::InvalidReply); } } }; VOLCANO_EXPORT std::shared_ptr<volcano::api::pm::Iface> create() { return std::make_shared<Impl>(); } #ifdef UNIT_TEST VOLCANO_EXPORT std::shared_ptr<volcano::api::pm::Iface> create(std::shared_ptr<volcano::fmk::msg::Iface> msg) { (void)msg; return std::make_shared<Impl>(); }; #endif // UNIT_TEST } // namespace pm } // namespace api } // namespace volcano 编译报错,怎么解决 In file included from /usr/include/x86_64-linux-gnu/c++/11/bits/c++allocator.h:33, from /usr/include/c++/11/bits/allocator.h:46, from /usr/include/c++/11/memory:64, from /home3/zhanghong/zhanghong/MEIG/MEIG_VOLCANO/src/apps/volcano_pm/volcano_pm_agent.cpp:24: /usr/include/c++/11/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = volcano::api::pm::Impl; _Args = {}; _Tp = volcano::api::pm::Impl]’: /usr/include/c++/11/bits/alloc_traits.h:516:17: required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = volcano::api::pm::Impl; _Args = {}; _Tp = volcano::api::pm::Impl; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<volcano::api::pm::Impl>]’ /usr/include/c++/11/bits/shared_ptr_base.h:519:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {}; _Tp = volcano::api::pm::Impl; _Alloc = std::allocator<volcano::api::pm::Impl>; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ /usr/include/c++/11/bits/shared_ptr_base.h:650:16: required from ‘std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = volcano::api::pm::Impl; _Alloc = std::allocator<volcano::api::pm::Impl>; _Args = {}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ /usr/include/c++/11/bits/shared_ptr_base.h:1342:14: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::allocator<volcano::api::pm::Impl>; _Args = {}; _Tp = volcano::api::pm::Impl; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’ /usr/include/c++/11/bits/shared_ptr.h:409:59: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::allocator<volcano::api::pm::Impl>; _Args = {}; _Tp = volcano::api::pm::Impl]’ /usr/include/c++/11/bits/shared_ptr.h:862:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = volcano::api::pm::Impl; _Alloc = std::allocator<volcano::api::pm::Impl>; _Args = {}]’ /usr/include/c++/11/bits/shared_ptr.h:878:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = volcano::api::pm::Impl; _Args = {}]’ /home3/zhanghong/zhanghong/MEIG/MEIG_VOLCANO/src/apps/volcano_pm/volcano_pm_agent.cpp:278:34: required from here /usr/include/c++/11/ext/new_allocator.h:162:11: error: no matching function for call to ‘volcano::api::pm::Impl::Impl()’ 162 | { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /home3/zhanghong/zhanghong/MEIG/MEIG_VOLCANO/src/apps/volcano_pm/volcano_pm_agent.cpp:46:5: note: candidate: ‘volcano::api::pm::Impl::Impl(std::shared_ptr<volcano::fmk::msg::Iface>)’ 46 | Impl(std::shared_ptr<volcano::fmk::msg::Iface> msg) : msg_(msg){}; | ^~~~ /home3/zhanghong/zhanghong/MEIG/MEIG_VOLCANO/src/apps/volcano_pm/volcano_pm_agent.cpp:46:5: note: candidate expects 1 argument, 0 provided /home3/zhanghong/zhanghong/MEIG/MEIG_VOLCANO/src/apps/volcano_pm/volcano_pm_agent.cpp:44:8: note: candidate: ‘volcano::api::pm::Impl::Impl(const volcano::api::pm::Impl&)’ 44 | struct Impl : public volcano::api::pm::Iface { | ^~~~ /home3/zhanghong/zhanghong/MEIG/MEIG_VOLCANO/src/apps/volcano_pm/volcano_pm_agent.cpp:44:8: note: candidate expects 1 argument, 0 provided /home3/zhanghong/zhanghong/MEIG/MEIG_VOLCANO/src/apps/volcano_pm/volcano_pm_agent.cpp:44:8: note: candidate: ‘volcano::api::pm::Impl::Impl(volcano::api::pm::Impl&&)’ /home3/zhanghong/zhanghong/MEIG/MEIG_VOLCANO/src/apps/volcano_pm/volcano_pm_agent.cpp:44:8: note: candidate expects 1 argument, 0 provided [ 51%] Built target volcano_manager_app [ 51%] Linking CXX static library ../../../lib/libgmock.a make[2]: *** [src/test/integration_test/volcano_api/volcano_pm/CMakeFiles/volcano_pm_test.dir/build.make:90: src/test/integration_test/volcano_api/volcano_pm/CMakeFiles/volcano_pm_test.dir/__/__/__/__/apps/volcano_pm/volcano_pm_agent.cpp.o] Error 1 make[1]: *** [CMakeFiles/Makefile2:5842: src/test/integration_test/volcano_api/volcano_pm/CMakeFiles/volcano_pm_test.dir/all] Error 2
08-14
[build] (.text._ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJP2OpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv[_ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJP2OpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv]+0x20): undefined reference to `opj_image_destroy' [build] /usr/bin/ld: (.text._ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJP2OpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv[_ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJP2OpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv]+0x2c): undefined reference to `opj_destroy_codec' [build] /usr/bin/ld: (.text._ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJP2OpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv[_ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJP2OpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv]+0x38): undefined reference to `opj_stream_destroy' [build] /usr/bin/ld: /usr/lib/aarch64-linux-gnu/libopencv_imgcodecs.a(loadsave.cpp.o): in function `std::_Sp_counted_ptr_inplace<cv::Jpeg2KJ2KOpjDecoder, std::allocator<cv::Jpeg2KJ2KOpjDecoder>, (__gnu_cxx::_Lock_policy)2>::_M_dispose()': [build] (.text._ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJ2KOpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv[_ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJ2KOpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv]+0x20): undefined reference to `opj_image_destroy' [build] /usr/bin/ld: (.text._ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJ2KOpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv[_ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJ2KOpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv]+0x2c): undefined reference to `opj_destroy_codec' [build] /usr/bin/ld: (.text._ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJ2KOpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv[_ZNSt23_Sp_counted_ptr_inplaceIN2cv19Jpeg2KJ2KOpjDecoderESaIS1_ELN9__gnu_cxx12_Lock_policyE2EE10_M_disposeEv]+0x38): undefined reference to `opj_stream_destroy' [build] /usr/bin/ld: /usr/lib/aarch64-linux-gnu/libopencv_imgcodecs.a(loadsave.cpp.o): in function `cv::imdecode_(cv::Mat const&, int, cv::Mat&) [clone .isra.0]': [build] (.text._ZN2cvL9imdecode_ERKNS_3MatEiRS0_.isra.0+0x41c): undefined reference to `cv::resize(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_<int>, double, double, int)' [build] /usr/bin/ld: /usr/lib/aarch64-linux-gnu/libopencv_imgcodecs.a(loadsave.cpp.o): in function `cv::imread_(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, int, cv::Mat&) [clone .isra.0]': [build] (.text._ZN2cvL7imread_ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRNS_3MatE.isra.0+0x22c): undefined reference to `cv::resize(cv::_InputArray const&, cv::_OutputArray const&, cv::Size_<int>, double, double, int)' [build] /usr/bin/ld: /usr/lib/aarch64-linux-gnu/libopencv_videoio.a(cap_gstreamer.cpp.o): in function `void cv::(anonymous namespace)::GSafePtr_release<_GstElement>(_GstElement**)': [build] (.text._ZN2cv12_GLOBAL__N_1L16GSafePtr_releaseI11_GstElementEEvPPT_+0x10): undefined reference to `g_type_check_instance_cast' [build] /usr/bin/ld: (.text._ZN2cv12_GLOBAL__N_1L16GSafePtr_releaseI11_GstElementEEvPPT_+0x14): undefined reference to `gst_object_unref' [build] /usr/bin/ld: /usr/lib/aarch64-linux-gnu/libopencv_videoio.a(cap_gstreamer.cpp.o): in function `void cv::(anonymous namespace)::GSafePtr_release<_GstPad>(_GstPad**)': [build] (.text.unlikely._ZN2cv12_GLOBAL__N_1L16GSafePtr_releaseI7_GstPadEEvPPT_+0x10): undefined reference to `g_type_check_instance_cast' [build] /usr/bin/ld: (.text.unlikely._ZN2cv12_GLOBAL__N_1L16GSafePtr_releaseI7_GstPadEEvPPT_+0x14): undefined reference to `gst_object_unref' [build] /usr/bin/ld: /usr/lib/aarch64-linux-gnu/libopencv_videoio.a(cap_gstreamer.cpp.o): in function `void cv::(anonymous namespace)::GSafePtr_release<_GstEncodingContainerProfile>(_GstEncodingContainerProfile**)': [build] (.text._ZN2cv12_GLOBAL__N_1L16GSafePtr_releaseI28_GstEncodingContainerProfileEEvPPT_+0x10): undefined reference to `g_type_check_instance_cast' [build] /usr/bin/ld: (.text._ZN2cv12_GLOBAL__N_1L16GSafePtr_releaseI28_GstEncodingContainerProfileEEvPPT_+0x14): undefined reference to `gst_object_unref' [build] /usr/bin/ld: /usr/lib/aarch64-linux-gnu/libopencv_videoio.a(cap_gstreamer.cpp.o): in function `cv::gst_initializer::~gst_initializer()': [build] (.text._ZN2cv15gst_initializerD2Ev[_ZN2cv15gst_initializerD5Ev]+0x28): undefined reference to `g_main_loop_unref' [build] /usr/bin/ld: (.text._ZN2cv15gst_initializerD2Ev[_ZN2cv15gst_initializerD5Ev]+0x34): undefined reference to `gst_deinit' [build] /usr/bin/ld: (.text._ZN2cv15gst_initializerD2Ev[_ZN2cv15gst_initializerD5Ev]+0x44): undefined reference to `g_main_loop_quit'图中报错如何解决
10-31
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhangzhangkeji

谢谢支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值