在指向结构的指针中访问数组

时间:2011-04-22 01:27:26

标签: c pointers c99 struct dereference

我有一个简单的结构:

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]出了问题。

4 个答案:

答案 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);

更改完成后,其余代码将按预期编译并运行。