c++ - 在函数返回值/参数和类请求的数据传输过程中是否复制了指向内存的指针?

标签 c++ pointers memory-management pass-by-reference shared-ptr

假设我有以下函数(其中 mVertexShader 是一个 std::shared_ptr< ID3D11VertexShader > 类成员,而 mRenderData 只是包含其他 D3D 内容的 POD):

void VertexShader::CreateShader( void )
{
    GVertexShader* raw_VertexShader = mVertexShader.get();

    mRenderData->Device->CreateVertexShader(
        mCompiledShader->GetBufferPointer(),
        mCompiledShader->GetBufferSize(),
        NULL,
        &raw_VertexShader
    );

    delete raw_VertexShader;
    raw_VertexShader = NULL;
} 

mVertexShader.get()返回原始指针,将删除 raw_VertexShader影响指针内部 mVertexShader.get() ,或者,虽然指向的内存相同,但指针本身却完全不同?

我猜是后者,因此为什么引用指针首先存在,但我想确保我的想法是正确的。

注意:我目前使用的是 MSVC++,但很高兴听到 MSVC++ 和 MinGW/GCC 实现它的方式是否存在任何显着差异。

注意 2: 如果我不清楚,我深表歉意 - 我在这里根本不是指 D3D 的语义,而是 C++ 语言本身在内存方面的语义管理、数据传输和动态内存分配。从这个意义上说,我试图准确理解当从函数返回原始指针时会发生什么。

即,假设 mVertexShader当我调用它的 get() 时,正在存储指向任意 VertexShader 的简单原始指针方法,它是否返回一个copied 指针,该指针指向与shared_ptr 中的内存地址相同的内存地址容器,或者它是一个完全的指针,已经被复制并返回,内存指向一个不同的地址?

最佳答案

这实际上完全是关于 std::shared_ptr 的语义。该语言非常乐于支持返回指向对象的指针、制作对象的拷贝并返回指向该对象的指针或增加对象的引用计数并返回指向它的指针的方法。如果你愿意,你可以做所有这些事情。

共享指针上的get 方法只是返回对象的原始指针。没有复制。你不应该永远删除这个指针,原因有二:

  1. 另一个对象可能有一个指向同一个对象的共享指针,而您将从它下面删除该对象。 (这就是共享指针的意义所在。)

  2. 当最后一个共享指针消失时,对象将被删除。删除一个对象两次是 UB,可能会导致您的代码崩溃。 (这也是共享指针的意义所在。)

让共享指针完成它们的工作。

请注意,如果您在共享指针上调用 get,则应确保在使用您获得的原始指针时一直保留该共享指针。否则,该对象可能不复存在。共享指针的逻辑是,只要你至少保留一个引用对象的共享指针,它就不会被删除,当最后一个这样的共享指针消失时,对象自动删除。

关于c++ - 在函数返回值/参数和类请求的数据传输过程中是否复制了指向内存的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11707453/

相关文章:

c++ - 获取节点在rapidjson中的偏移量?

c++ - 如何根据类型特征进行 constexpr 计数

c - ptr、*ptr 和 &ptr 之间的区别

c++ - shared_ptr 会自动释放内存吗?

c++ - 为什么在这种情况下编译动态库会出错呢?

c - 尽管分配了指针,但指针仍指向 Null

c - 结构指针实现方法

c - c中的堆栈内存布局

delphi - 在此过程中,Delete 是否做了任何事情?

c++ - 使用 CScope 查找函数调用(非定义)(C/C++)