2011-04-22 22 views
0

我有一个简单的结构:在一个指针访问阵列一个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->的东西(假设不是,我只是将它添加到第一槽至少,位置管理做过的):

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]有什么问题。

回答

3

根据C标准,void没有size - sizeof(void)是未定义的。 (一些实施方式使它的sizeof(int)的,但是,这是不符合规定。)

当你有Foo类型的阵列,此表达式:

array[3] 

添加3 *的sizeof(富)到地址存储在数组中,然后推断它。这是因为这些值全部在内存中打包在一起。由于sizeof(void)是不确定的,所以你不能这样做void array(实际上你甚至不能使用 void array,只有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-的第一阵列成员>东西时,它不是,并会处理&东西的指针,这是一个char **,就好像它只是一个char *。

+0

这很有帮助。我会使用指针算术来强化未来项目吗? – Rio 2011-04-22 01:45:55

+0

你说得对。但在这种情况下,它是“sizeof(void *)”,而不是“sizeof(void)”。 – shinkou 2011-04-22 01:50:23

+0

我不确定你的意思。 Strncpy会复制一个字符串(这只是一个字符数组)。如果你想在一个大缓冲区中将多个stings连接在一起,你可以在偏移指针上使用strncpy,但是使用strncat会更容易。 – 2011-04-22 01:52:34

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

sizeOfThings是什么初始化为?可能它可能有垃圾并导致错误。即使它默认初始化为,那么malloc返回NULL(malloc(20 * 0) ;)。所以,我怀疑 - 看到

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

@Rio - 警告清楚地表明它 - 'test.c:10:warning:取消引用'void *'指针' – Mahesh 2011-04-22 01:39:07

+0

sizeOfThings设置为string的sizeof(char *)和int的sizeof(int)。 – Rio 2011-04-22 01:39:52

+0

@Rio - 您正在请求大小为** 20 * sizeOfThings **的内存。但是在执行'malloc'语句时,'sizeOfThings'值是什么?同样@shinkou建议第二个参数应该是'thing'。 – Mahesh 2011-04-22 01:41:37

0

尝试,如果这能解决你的问题:

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

然后,投了三分球摆脱了警告,但你必须确保你” re要做

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

两件事情:

首先,肯定有一些错误使用D->的东西[0]。事物实际上是一个指针,约定是指针和数组基本上是可以互换的(有一些例外),数组的名称将始终指向数组的第一个元素。其次,strncpy的功能签名是char * strncpy(char * destination,const char * source,size_t num);。所以要做到这一点,我们必须将d->从void *转换为char *,并确保我们将char *(只是事物)与char **(这是事物&)进行通信。

所以我们想,而不是这样的说法:

函数strncpy((字符*)D->的东西,事情,D-> sizeOfThings);

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