void *作为函数参数

时间:2019-01-18 13:03:01

标签: c

我在使用void *时遇到问题。我应该如何将这个clean_buffer函数用于int和float数组。

void clean_buffer( void *ptr, int n)
{
    for( int i = 0; i < n; i++)
        ptr[i]=0;
}
int main(void)
{
   float  *pf;
   int    *pi;

   pf = (float *) malloc(10*sizeof(float));
   pi = (int *)malloc(10*sizeof(int));


   clean_buffer( (float *)pf, 10);
   clean_buffer( (int *)pi, 10);

    return 0;
}

6 个答案:

答案 0 :(得分:2)

void 是一个非值,您不能使用*((void*) x) = v;,并且使用 cast 使用指向其他类型的指针是危险的,因为大小可能不一样

但是,如果您将其设置为0,则可以使用 memset 或替换 malloc 我的 calloc ,它对于拥有clean_buffer

int main(void)
{
   float  *pf;
   int    *pi;

   pf = calloc(10, sizeof(float));
   pi = calloc(10, sizeof(int));

   return 0;
}

答案 1 :(得分:2)

类型void没有大小。因此,您不能使用void *清除数组。 出于相同的原因,您不能取消引用该类型。

您必须强制转换为具有特定类型的指针:

void clean_buffer(void *ptr, size_t n)
{
    unsigned char *my_ptr = ptr;
    for (int i = 0; i < n; i++)
        my_ptr[i]=0;
}

您需要注意传递给函数的大小不能为数字或数组,因为编译器无法使用void*指针进行指针算术运算。 对于尺寸,您应该使用size_t

相反,您必须以字节为单位传递数组的大小:

int main(void)
{
   float  *pf;
   int    *pi;

   pf = malloc(10*sizeof(float));
   pi = malloc(10*sizeof(int));

   clean_buffer( pf, 10*sizeof(float));
   clean_buffer( pi, 10*sizeof(int));

   return 0;
}

或者您需要传递可用于确定数据类型和/或大小的任何其他信息。

也: 在C中不需要强制转换malloc的返回值。 将clean_buffer的参数强制转换为变量已具有的类型是没有用的。指针类型始终会转换为void *,因为这是函数所期望的。

注意: 其他答案和评论提到您可以简单地将指针传递到memset或使用calloc等。 对于这种非常特殊的情况,这可能是正确的,但是如果您想做的事情不仅仅是简单地将内存清零,那么与void *指针相同的方面同样适用。在这种情况下,memsetcalloc毫无帮助。

答案 2 :(得分:1)

  

我在使用void *时遇到问题。我应该如何将这个clean_buffer函数用于int和float数组(?)

其他人提到了一些有用的事情,例如需要sizeof来查找大小,不进行强制转换以及使用calloc()进行零初始化内存分配的替代方法。


要添加:

* object_pointer的大小

使用sizeof *object_pointer查找尺寸。与类型编码相比,它更不容易出错,更易于检查和维护。

// clean_buffer( (float *)pf, 10);
// clean_buffer( (int *)pi, 10);

// cast not needed
clean_buffer(pf, sizeof *pf * 10);  // No need to mention type!
clean_buffer(pi, sizeof *pi * 10);

易失性

在最终使用完内存后,很容易对其进行清理,因此,在考虑到内存安全性时,有理由使用memset()。而是使用volatile来防止clean_buffer()自身被优化。

void clean_buffer(void *ptr, size_t n) {
  volatile unsigned char *vuc = ptr;
  for(size_t i = 0; i < n; i++)
    vuc[i]=0;
  }
}

答案 3 :(得分:0)

您将ptr强制转换为适当的类型,以便可以取消引用以清除其指向的内容;您知道的东西指向您要清除的i个项目的类型。

答案 4 :(得分:0)

  

void clean_buffer(void * ptr,int n)

此函数需要一个空*作为参数。

  

clean_buffer((float *)pf,10);

在这里,您要强制转换为浮动指针。所以这是要求的另一种类型

void也没有大小,因此您不能在ptr上真正使用[]

答案 5 :(得分:0)

malloc本身会返回一个空指针,因为它实际上并不知道您要为哪种类型分配内存。因此,您还需要使用传递给malloc的相同大小来清除缓冲区。

您可以使用memset并传递整个缓冲区的大小来清除它,而不必担心它的类型。

void clean_buffer( void *ptr, size_t n)
{
    memset(ptr, 0, n)
}
int main(void)
{
   float  *pf;
   int    *pi;

   pf = (float *) malloc(10*sizeof(float));
   pi = (int *)malloc(10*sizeof(int));


   clean_buffer(pf, 10*sizeof(float));
   clean_buffer(pi, 10*sizeof(int));

    return 0;
}

另外,如其他人所建议的那样,您可以根据需要使用calloc