繁体   English   中英

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

[英]Accessing arrays in a pointer to a struct

我有一个简单的结构:

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是sizeof(int)。

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

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]

根据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 *。

Demo *d = malloc(sizeof(Demo));
if (d != NULL) {
    d->things = malloc(20 * sizeOfThings); // We'll have a max of 20 things
}

sizeOfThings初始化为什么? 可能是有垃圾,并导致了错误。 即使默认将其初始化为0malloc也会返回NULL( malloc( 20 * 0 ) ; )。 因此,我怀疑-

strncpy(d->things[0], &thing, d->sizeOfThings);
      // ^^^^^^^^^^ causing the error.

尝试查看是否可以解决您的问题:

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

然后,强制释放指针以摆脱警告,但是您必须确保要执行的操作

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

两件事情:

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

其次,strncpy的功能签名是char * strncpy(char *目标,const char *源,size_t num); 因此,要使此工作有效,我们必须将d-> thing从void *转换为char *,并确保我们将事物作为char *(只是事物)与char **(这是事物&)传递。

因此,我们希望使用以下语句:

strncpy((char *)d->事物,事物,d-> sizeOfThings);

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM