You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++中实现非构造函数的指定内存地址调用?

如何在C++中实现非构造函数的指定内存地址调用?

咱们先拆解一下你遇到的问题核心:C代码里可以直接调用接收指针参数的函数,把结果直接写到指定内存;但对应的C函数是返回对象的形式,现在要在标准C里模拟这种“把结果写入未初始化内存”的行为,同时和你给的C代码语义完全对齐。

下面是通用的标准C++解决方案,直接替换你代码里的/* what? */即可:

#include <new>
#include <utility>  // 引入std::move做优化

class external_class{
public:
    external_class();
    ~external_class();
    unsigned short data;
};

external_class external_function();

extern "C" void construst_external_class_at(external_class *out){
    new(out) external_class;
}

extern "C" void return_external_function_at(external_class *out){
    // 在指定内存上移动构造external_function返回的对象
    new(out) external_class(std::move(external_function()));
}

为什么这么写?

  1. placement new的必要性:out指向的是未初始化的原始内存,不能直接赋值(赋值要求左操作数是已经构造好的对象),所以必须用placement new在这块内存上构造对象——这和你用placement new调用构造函数的逻辑完全一致。
  2. std::move的优化作用:external_function()返回的是临时对象,用std::move可以把这个临时对象的资源“转移”给新构造的对象,避免无意义的深拷贝(如果你的类定义了移动构造函数,就会走移动逻辑;没定义的话会自动 fallback 到拷贝构造,语义也是安全的)。
  3. 可移植性拉满:这个写法完全遵循C++标准,不依赖任何编译器/ABI的私有细节,比直接调用底层的ABI函数靠谱多了。

针对特殊场景的优化写法

如果你的external_class是平凡可拷贝类型(比如只有基本数据成员,没有自定义的构造/拷贝/移动/析构函数),还可以用std::memcpy来做更高效的内存拷贝:

#include <new>
#include <cstring>

// ... 其他代码不变 ...

extern "C" void return_external_function_at(external_class *out){
    auto temp = external_function();
    std::memcpy(out, &temp, sizeof(external_class));
}

但注意:这种写法只适用于平凡可拷贝类型,如果类里有虚函数、动态分配的内存或者其他非平凡成员,用memcpy会直接破坏对象的内部状态,导致未定义行为,所以通用场景下优先选第一种placement new的写法。

最后提个关键注意事项

和placement new创建的所有对象一样,当你不再需要out指向的对象时,得手动调用析构函数(如果类有非平凡析构的话):

out->~external_class();

不然会导致资源泄露哦。

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 07:49:49