c++ - 如何从原始指针中获取 shared_ptr?
问题描述
我在做 c/c++ 混合编程,像这样:
common.h
#ifdef __cplusplus
typedef opentracing::Span CTraceSpan;
#else
struct CTraceSpan;
typedef struct CTraceSpan CTraceSpan;
#endif
extern "C" CTraceSpan* c_StartServerSpan();
extern "C" CTraceSpan* c_FinishServerSpan(CTraceSpan *span);
跟踪2cpp
extern "C" CTraceSpan* c_StartServerSpan(){
auto server_span = hwtrace::StartServerSpan();
return server_span.get();
}
extern "C" CTraceSpan* c_FinishServerSpan(CTraceSpan *span){
std::shared_ptr<opentracing::Span> s_span(std::move(span));
auto server_span = hwtrace::FinishServerSpan(s_span);
return server_span.get();
}
在 trace.c 中
CTraceSpan *span = NULL;
span = c_StartClientSpan();
c_FinishClientSpan(span);
当我运行我的项目时,出现错误:
分段错误(核心转储)
下面的问题,说不能从原始指针创建shared_ptr,但我需要将一个指针从c传输到c++,我该怎么办?
你永远不应该像这里那样从普通指针创建 shared_ptr :
shared_ptr<ParticleEmitter>(&e)
这会尝试释放 ParticleEmitter 两次。一次作为持有 ParticleEmitter 对象的向量超出范围,一次作为 shared_ptr 超出范围。
解决方案
下面的问题说不能从原始指针创建 shared_ptr
该特定答案通常是错误的(尽管在特定情况下是正确的)。您可以从原始指针创建共享指针。您不能从不拥有该对象的指针创建共享指针。
但我需要将指针从 c 传输到 c++,我该怎么办?
这取决于。指向的对象是如何分配的?是否需要手动解除分配(即它是动态分配的)?什么时候应该(什么时候不能)释放它?谁应该负责释放(C 或 C++)?应该如何释放它(这应该直接取决于它是如何分配的)?
如果对象是静态的或自动的,那么您不需要特别做任何事情。
如何从原始指针 [来自 C] 中获取 shared_ptr?
假设对象是在 C 中使用 分配的malloc
,并被赋予负责释放的 C++ 代码,然后像这样:
std::shared_ptr<CTraceSpan> s_span(span, std::free);
分配某些东西并将弄清楚如何解除分配的责任推给客户端代码通常是糟糕的 API 设计。因此,对于分配某些东西的每个函数,通常 C API 都会有一个释放函数,允许客户端从释放的细节中解耦。当分配的对象本身具有拥有指针的动态内存时,这一点尤其重要。
假设deallocate_ctrace_span
在这种情况下是这样的释放函数:
std::shared_ptr<CTraceSpan> s_span(span, deallocate_ctrace_span);
话虽如此,看来您的指针实际上并未在 C 中分配,而是在 C++ 中分配。您的示例不完整,并且不清楚您打算如何使用共享指针。
推荐阅读
- python - 如何更有效地创建/保存 2bit 图像?
- typescript - 在 docker 中运行时,craco build 在编译 typescript 文件时失败
- sql - 有没有办法创建数量为零的营业月
- mysql - 可能由于多个 AND 导致的语法错误?
- java - 从某个字符到另一个字符的 Java 正则表达式子字符串
- swift - 如何快速获取json对象中的所有键
- react-native - 将组件设置为在屏幕上“浮动”而不占用空间
- c# - Binaryreader Readint32() 返回太大的值或 -ve 值
- python - 如何在 Keras 中加快对具有自定义损失函数的模型的训练?
- angular - 绑定角度形式选择选项不起作用