【问题标题】:C++: How to get the address of a float pointer and convert it to void**C++:如何获取浮点指针的地址并将其转换为 void**
【发布时间】:2018-10-27 10:39:11
【问题描述】:

在 C++ 编程中,我经常需要获取指针的地址并将其转换为void **。例如,通常在使用 CUDA 时:

int main() {
    float *data;
    size_t size = sizeof(float) * 1024;

    CUDA_CHECK(cudaMalloc((void **)&data, size));   // question about this line
    ...
    CUDA_CHECK(cudaFree(static_cast<void *>(data)));

    return 0;
}

我的问题是使用 C 风格类型转换将 float ** 转换为 void ** 让我很恼火,因为我不想在 C++ 编程中使用它。

到目前为止,我一直在使用reinterpret_cast&lt;void **&gt;(&amp;data),但我对此并不满意。出于某种原因,我认为这不是正确的做法。

我曾经非常愚蠢地尝试过&amp;static_cast&lt;void *&gt;(data),因为尝试从右值获取地址显然失败了。

我在 Google 和 Stack Overflow 上进行了一些搜索,但我很难为查询找到合适的关键字。

我也一直在学习右值引用的概念,但我不认为它是为这个问题而设计的。

所以我的问题是,在这种情况下,从 float ** 转换为 void ** 的正确 C++ 方法是什么?另外,有没有办法将static_cast 到void * 并仍然从返回值中获取地址,比如右值引用? (PS:我还是不太明白rvalue reference,如果这是菜鸟的错误请见谅)

编辑 --------------

对不起,我没有说清楚。我不想在这里声明void *。我只是想以某种方式做一个“正确的”C++ 演员来完成这件事,最好只用一行。

更多编辑 ----------

我明白使用void * 的正确方式,正如@M.M 在下面指出的那样(事实上,这正是我一段时间以来一直在做的事情)。我只是好奇是否有任何适当的方法可以避免使用void *。

【问题讨论】:

  • 使用reinterpret_cast&lt;void**&gt;(&amp;data) 是在这里投射的“正确”方式。
  • 为什么这个库采用void ** 参数,而void * 就可以了?
  • @SidS • 看起来它是 C++ 中 void*&amp; 参数的 C API 等效项。
  • @SidS 它是一个“out”参数,函数“返回”一个void * 值并使用函数返回值作为错误代码

标签: c++ pointers casting


【解决方案1】:

我会这样做:

void *newdata;
CUDA_CHECK(cudaMalloc(&newdata, size));
float *data = static_cast<float *>(newdata);

CUDA_CHECK(cudaFree(data)); // or pass newdata, doesn't matter

显然我会用 RAII 将这些块包装成一个智能指针。

【讨论】:

  • 对不起,我没有在 OP 中说清楚。我知道这是一个很好的方法。但是如果我不想使用void * 指针怎么办?我想知道是否有任何方法可以避免这种情况。现在正在编辑 OP...
  • @TerryTsao 这个答案显示了正确的方法。带有reinterpret_cast 的版本(完全等同于 C 风格的演员表)是“应该工作”的未定义行为,看来你的蜘蛛侠感觉确实在告诉你依赖 UB 工作是不好的
  • @M.M 感谢您的评论。我也在想同样的事情。
猜你喜欢
  • 2015-04-24
  • 2016-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多