我有一个简单的结构:
typedef struct {
void *things;
int sizeOfThings;
} Demo;
事物旨在包含一系列单独的“事物”,例如字符串或整数。 我创建了一个指向它的指针:
Demo * Create(int value) {
Demo *d = malloc(sizeof(Demo));
if (d != NULL) {
d->sizeOfThings = value;
d->things = malloc(20 * value); // We'll have a max of 20 things
}
}
例如, value
是一个int数组的sizeof(int)。
如果在另一个函数中我想在d->事物中插入一些东西(假设至少不是我只是将它添加到第一个插槽中,在其他地方完成位置管理):
char * thing = "Me!";
strncpy(d->things[0], &thing, d->sizeOfThings);
我绕过了strncpy区域
test.c:10: warning: pointer of type ‘void *’ used in arithmetic
test.c:10: warning: dereferencing ‘void *’ pointer
test.c:10: error: invalid use of void expression
我只是想了解void *的用法,以此来概括我的函数。我怀疑d->things[0]
出了问题。
答案 0 :(得分:3)
根据C标准,void没有大小 - sizeof(void)未定义。 (有些实现使它成为sizeof(int),但这是不合规的。)
当你有一个foo类型的数组时,这个表达式为:
array[3]
将3 * sizeof(foo)添加到存储在数组中的地址,然后对其进行处理。那是因为这些值都在内存中打包在一起。由于sizeof(void)未定义,因此无法对void数组执行此操作(事实上,您甚至不能拥有 void数组,只能使用void指针。)
在将其作为数组处理之前,必须将任何void指针强制转换为另一个指针类型:
d->things = malloc(20 * sizeof(int));
(int *)(d->things)[0] = 12;
但是,请记住,您甚至不必这样做就可以使用strncpy。 Strncpy可以接受一个空指针就好了。但你错误地使用了strncpy。您的strncpy调用应如下所示:
strncpy(d->things, thing, d->sizeOfThings);
你的版本应该做的是尝试将d->事物的第一个数组成员视为指针,当它不是时,并且会处理& thing,这是一个char **,好像它只是一个char *。
答案 1 :(得分:0)
Demo *d = malloc(sizeof(Demo));
if (d != NULL) {
d->things = malloc(20 * sizeOfThings); // We'll have a max of 20 things
}
sizeOfThings
初始化为什么?可能它可能有垃圾并导致错误。即使默认情况下将其初始化为 0 ,malloc
也会返回NULL(malloc( 20 * 0 ) ;
)。所以,我怀疑 -
strncpy(d->things[0], &thing, d->sizeOfThings);
// ^^^^^^^^^^ causing the error.
答案 2 :(得分:0)
尝试查看这是否可以解决您的问题:
char *thing = "Me!";
strncpy(&d->things[0], thing, d->sizeOfThings);
然后,施放指针以摆脱警告,但你必须确定你将要做什么
char *thing = "Me!";
strncpy((char *) &d->things[0], (const char *) thing, d->sizeOfThings);
答案 3 :(得分:0)
两件事:
首先,使用 d->事[0] 肯定有问题。 d->事实上是一个指针,常规是指针和数组基本上是可以互换的(有一些例外),数组名称总是指向数组的第一个元素。
其次,strncpy的功能签名是 char * strncpy(char * destination,const char * source,size_t num); 。因此,为了使这项工作,我们必须将d-&gt;事物从void *转换为char *,并确保我们将事物作为char *(只是事物)与char **(这是事物&amp;)传递。< / p>
所以我们想要这个陈述:
strncpy((char *)d-&gt; thing,thing,d-&gt; sizeOfThings);
更改完成后,其余代码将按预期编译并运行。