#include<stdio.h>
int main()
{
int a;
int *p = &a;
void *z = p;
char *c = z;
}
上面的代码编译并不一定会有报错和告警信息,但有些是需要注意的。
分析:
-
int a;
:定义了一个整型变量a。 -
int *p = &a;
:定义了一个指向整型变量的指针p,指向变量a的地址。 -
void *z = p;
:定义了一个void类型的指针z,并将指针p的值(即a的地址)赋给z。这也是合法的,因为void指针可以接受任意类型的指针值。 -
char *c = z;
:这一行是关键。在这里,你将void指针z的值(即a的地址)赋给了char类型的指针c。在C语言中,将void指针赋给其他类型的指针(如char *、int *等)是不安全的,因为它们可能有不同的大小和语义。
在实际应用中,通常不会直接将void *类型的指针赋值给char *类型的指针,除非确保在后续操作中不会导致类型错误或者访问越界。
比较推荐的做法为:将一个void *类型的指针赋值给具体类型(如int *、char *)的指针时,进行显式的类型转换。
#include<stdio.h>
int main()
{
int a;
int *p = &a;
void *z = p;
int *c = (int *)z;
}
案例分析:
extern void *__kmalloc_fake;
static inline void *kmalloc(size_t s, gfp_t gfp)
{
if (__kmalloc_fake)
return __kmalloc_fake;
return malloc(s);
}
static inline void *kzalloc(size_t size, gfp_t flags)
{
return kmalloc(size, flags | __GFP_ZERO);
}
static inline void *kmalloc_array(size_t n, size_t size, gfp_t flags)
{
if (size != 0 && n > SIZE_MAX / size)
return NULL;
return __kmalloc(n * size, flags);
}
static inline void *kcalloc(size_t n, size_t size, gfp_t flags)
{
return kmalloc_array(n, size, flags | __GFP_ZERO);
}
struct tty_driver {
struct cdev *cdevs;
struct tty_struct **ttys;
unsigned int nr;;
};
int main()
{
struct tty_driver *driver;
driver = kzalloc(sizeof(struct tty_driver), GFP_KERNEL);
driver->nr = 10;
driver->ttys = kcalloc(driver->nr, sizeof(*driver->ttys), GFP_KERNEL);
driver->cdevs = kcalloc(driver->nr, sizeof(*driver->cdevs), GFP_KERNEL);
}
- 上面的案例中kzalloc与kcalloc的函数返回值皆是void *;
万能公式:
指针变量 = 申请空间函数(数量 * sizeof(指针变量解引用))
注:指针变量可以是1级指针,2级指针,...