我想构建一个结构,它可以保存简单的数据类型,如整数或该结构的数组。
结构如下:
typedef struct data_s {
size_t size; // size of memory data is pointing to
void * data; // pointer to data (array of data_t or simple type)
} data_t;
我简化了它,通常结构中存储了更多的信息
我写了函数来设置和获取整数值,它们工作!
现在我尝试编写用于创建数组和设置和获取值的函数,它们不起作用
我使用gdb来找到它失败的地方。它告诉我,我的解除引用并不像我期望的那样工作。我使用以下内容:
((data_t**)(data->data))[i]
并且我遇到了访问冲突。
如果有人能告诉我我的错误,那将会很棒。这是一个工作的代码示例,我已经最小化了代码,你没有我的程序的开销(也删除了错误处理)。代码在xubuntu 13.10和3.11内核上使用gcc -g main.c -o test
和gcc 4.8.1编译时没有任何错误
#include <stdio.h>
#include <stdlib.h>
typedef struct data_s {
size_t size;
void * data;
} data_t;
void set_integer(data_t *data, int value){
data->size = sizeof(int);
data->data = malloc(data->size);
*((int*)(data->data)) = value;
}
void get_integer(data_t *data, int *value){
(*value) = *((int*)(data->data));
}
void create_array(data_t *data, size_t len){
data->size = sizeof(data_t) * len;
data->data = malloc(data->size);
int i;
for(i=0; i<data->size; i++){ //initialize array
((data_t**)(data->data))[i]->data = NULL;
((data_t**)(data->data))[i]->size = 0;
}
}
void set_array(data_t *data, int index, data_t *value){
((data_t**)(data->data))[index]->data = value->data;
((data_t**)(data->data))[index]->size = value->size;
}
void get_array(data_t *data, int index, data_t *value){
value->data = ((data_t**)(data->data))[index]->data;
value->size = ((data_t**)(data->data))[index]->size;
}
void free_data(data_t *data, int is_array){
if(is_array){
int i;
for(i=0; i<(data->size / sizeof(data_t)); i++)
free(((data_t**)(data->data))[i]->data);
}
free(data->data);
}
int main(int argc, char**argv){
data_t data;
set_integer(&data, 42);
int val;
get_integer(&data, &val);
printf("expect 42; has: %d\n", val);
free_data(&data, 0);
data_t element;
create_array(&data, 3);
int i;
for(i=0; i<3; i++){
set_integer(&element, i*2);
set_array(&data, i, &element);
}
for(i=0; i<3; i++){
get_array(&data, i, &element);
get_integer(&element, &val);
printf("index: %d; value: %d\n", i, val);
}
free_data(&data, 1);
return 0;
}
答案 0 :(得分:2)
((data_t**)(data->data))[i]
,尝试
((data_t*)(data->data))[i]
编辑:要访问成员,请使用类似
的内容((data_t*)data->data)[i].data = NULL;
((data_t*)data->data)[i].size = 0;
答案 1 :(得分:1)
data->data
指向什么?那么,data->data = malloc(data->size);
行告诉你:它指向未初始化的记忆。
问题是,在尝试取消引用从此内存中读取的指针之前,不要在该内存中存储任何内容。 I. e。 (data_t**)data->data
没问题,((data_t**)data->data)[index]
会产生{{1>} 未定义值,并且由于该值未定义,因此使用data_t*
取消引用指针是未定义的行为
如果你想创建一个((data_t**)data->data)[index]->data
个对象的数组,一个间接就足够了,i。即使用
data_t
答案 2 :(得分:1)
((data_t**)(data->data))[i];
在上面的语句中,data->data
计算结构变量data
的{{1}}成员(您应该使用不同的标识符),类型为data
。现在,您希望将void *
指向缓冲区,该缓冲区是data->data
类型的对象数组。这意味着您必须将data_t
投射到data->data
,而不是data_t *
。因此,您应该将上述语句更改为
data_t **
代码中的任何地方。另请注意,((data_t *)(data->data))[i];
采用free
类型的参数,因此您无需在将指针传递给void *
之前投射指针。