【问题标题】:What is the difference between (void **)&x and (void *)x?(void **)&x 和 (void *)x 有什么区别?
【发布时间】:2012-08-09 06:44:48
【问题描述】:

(void **)&x 和 (void *)x 有什么区别?我会给你一些代码,请帮助我。

float *xd;
int size=width*width*size(float);
cudaMalloc((void **)&x,size); 1
cudaMalloc((void *)x,size);   2
cudaMalloc(&x,size);          3
cudaMalloc(*x,size);          4

cudaFree(xd);

我只是想知道区别。

cudaMalloc()函数的第一个参数是一个指针变量的地址,分配后必须指向分配的对象。指针变量的地址应该转换为 (void **) 因为函数需要一个通用指针值;内存分配函数是一个通用函数,不限于任何特定类型的对象。此地址允许 cudaMalloc() 函数将分配对象的地址写入指针变量。3 cudaMalloc() 函数的第二个参数以字节为单位给出要分配的对象的大小。这第二个参数的用法与C malloc() 函数的size参数一致。

【问题讨论】:

  • C++decl 可能在这里有用
  • 和&x和x的区别差不多。如果你不知道为什么你会认为两个截然不同的事情是相同的,这样的问题就没有用处。

标签: c pointers cuda gpgpu gpu


【解决方案1】:

为了让您更好地理解为什么您经常写(void**)&var(void**)&var,请考虑以下几点:

cudaMalloc 在 GPU 上分配内存。它引用的内存类型是void*,因为它并不真正关心数据类型。

一旦我们在刚刚分配的cudaMalloc 中获得了该内存的地址,我们就需要以某种方式将其返回给调用者。但是所有 CUDA API 函数都返回错误代码(或成功代码),任何额外返回的数据都必须通过参数引用传回。

C 语言没有传递引用,因此您实际上需要将指针传递给您希望函数存储结果的变量。由于要存储指针值,因此需要传递一个指向指针的指针。因此void** 类型。

如果想用类似的方式封装 malloc,可以这样写:

void myMalloc(void** ret, size_t size) {
    void* mem = malloc(size);
    *ret = mem;
}

现在,如果您将(void**)&var 传递给myMalloc,该函数将能够覆盖var 的值——因为ret 将指向var 变量。

这是否使它更清楚?

【讨论】:

  • 但这是未定义的行为;您需要使用void* 临时
  • @DavisHerring 你指的是什么?
  • 抱歉不清楚:通过(void**)&var 生成的指针存储是未定义的行为(除了var 实际上是void* 类型的琐碎情况)。 cudaMalloc的使用方式是float *f; {void *v; if(cudaMalloc(&v,n*sizeof*f)) …; f=v;}
  • 对于大多数架构和大多数编译器,您可以在 void**T** 之间进行转换(其中 T 不是函数)。而对于 C 标准 - 它不适用,因为根据定义,CUDA 超出了标准的范围,因此是一个很大的未定义行为。
  • 您可以进行强制转换,但允许优化器假设结果不会发生存储(除非首先将其强制转换回正确的类型)。这个问题实际上与 CUDA 无关,只是作为一个例子,即使 C/CUDA 实现对实用性做出的让步(这不是 UB,只是因为它是一个扩展)碰巧没有破坏,也没有理由鼓励破坏习语它(今天)。
【解决方案2】:

它们只是完全不同。

这个:

(void **)&x

获取x 的地址并将其转换为void**(指向void 的指针)。

这个:

(void *)x

获取x并将其转换为void*

它们都是指针,但它们指向内存中完全不同的位置(除非x 恰好包含它自己的地址),并且它们属于不同的类型。

如果您想向我们展示代码,向我们展示实际编译的代码会很有帮助。复制并粘贴您的实际源代码;不要重新输入。您还没有向我们展示x 的声明(xdx 的拼写错误吗?),size(float) 是语法错误(您的意思是sizeof(float)?)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-16
    • 2017-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多