我在使用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;
}
答案 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 *
指针相同的方面同样适用。在这种情况下,memset
或calloc
毫无帮助。
答案 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
。