0

我有一个简单的结构:

typedef struct {
    void *things;
    int sizeOfThings;
} Demo;

things 旨在包含一组单独的“事物”,例如字符串或整数。我创建了一个指向它的指针:

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例如,对于整数数组,sizeof(int) 是 sizeof(int)。

如果在另一个函数中我想在 d->things 中插入一些东西(至少假设不是我只是将它添加到第一个插槽,位置管理在其他地方完成):

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]

4

4 回答 4

4

根据 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 可以接受一个 void 指针就好了。但是您错误地使用了 strncpy 。您的 strncpy 调用应如下所示:

strncpy(d->things, thing, d->sizeOfThings);

您的版本会尝试将 d->things 的第一个数组成员视为指针,而实际上它不是指针,并且会将 &thing(它是一个 char **)当作只是一个 char * 来处理。

于 2011-04-22T01:40:09.850 回答
1

尝试看看这是否能解决您的问题:

char *thing = "Me!";
strncpy(&d->things[0], thing, d->sizeOfThings);

然后,投射指针以消除警告,但你必须确定你要做什么

char *thing = "Me!";
strncpy((char *) &d->things[0], (const char *) thing, d->sizeOfThings);
于 2011-04-22T01:35:09.960 回答
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.
于 2011-04-22T01:32:12.287 回答
0

两件事情:

首先,使用d->things[0]肯定有问题。d->things 实际上是一个指针,约定是指针和数组基本上是可互换的(除了少数例外),并且数组名称将始终指向数组的第一个元素。

其次,strncpy 的函数签名是char* strncpy(char* destination, const char* source, size_t num); . 因此,为了完成这项工作,我们必须将 d->thing 从 void* 转换为 char* 并确保我们将 thing 作为 char*(只是事物)与 char**(即 thing&)传递。

所以我们想要这个语句:

strncpy((char*)d->things, thing, d->sizeOfThings);

一旦更改到位,其余代码将按预期编译和运行。

于 2011-04-22T05:15:52.010 回答