我正在用C语言开发一个用于通信的驱动程序,并且交换的消息没有固定的大小。通信总线的建议是将结构用于多主题,这也是我的理由。
我的第一个问题:我必须继续收听新消息,当我收到新消息时,我必须处理消息数据(它有延迟)并仍然在收听新消息。
第一个解决方案:在获取处理数据的新消息时使用线程。
我的第二个问题:消息中的数据可以包含结构的多个数据,而我的通信器需要使用结构来组织这个多个值。
第二个解决方案:使用struct hack来分配struct的内存动态大小。
我当前的问题:当我将结构作为参数传递给线程或任何函数时,我正在丢失数据结构并获取错误的值。
简短的测试是:
typedef struct test{
int size;
int value[];
} test;
void allocation(test *v){
test *aux = (test *)malloc(sizeof(test)+3*sizeof(int));
int i;
aux->value[0] = 2;
aux->size = 3;
aux->value[1] = 1;
aux->value[2] = 5;
printf("Teste1 %d\n",aux->size);
for(i=0; i < aux->size; i++){
printf("%d\n", aux->value[i]);
}
*v = *aux;
}
void cleanup(test *v){
free(v);
}
int main(int argc, char *argv[]){
test v;
int i;
allocation(&v);
printf("Teste2 %d\n",v.size);
for(i=0; i < v.size; i++){
printf("%d\n", v.value[i]);
}
//cleanup(&v);
return 0;
}
在这个测试中,我在第一次打印时获得了正确的值,在第二次打印时得到了错误的值(只有v.size
给出了正确的值)。
我的结构比测试中的结构稍微复杂一点。我的结构就像:
typedef struct test1{
double v1;
double v2;
} test1;
typedef struct test2{
int size;
test1 values[];
} test2;
一旦我拥有修复所需的所有元素,你知道如何在该函数中修复我的内存结构吗?请记住,我还可以分配多个test2
数据,这是可取的(不是必需的)。
答案 0 :(得分:2)
这里的事情是你为不完整的成员int value[]
分配结构;虽然原则上可以按值复制两个结构(这实际上是在写*v = *aux
时会发生的情况);但是,由于编译器不知道成员大小value[]
将在运行时采用,v
的“sizeof”以及*aux
的大小始终为4,即已知一个int成员size
的大小。因此,只复制它,而value[]
- 数组只是不被复制。
解决这种情况的方法是需要一个指向指针的指针(即allocation(test **v)
,这样保留的内存可以直接分配给它,使用指向main的struct test的指针,即{{1 },并致电test *vptr
。
如果你无法避免将尊重传递给值(而不是引用指向该值的指针),我想你必须使用allocation(&vptr)
来传输内容。但这实际上没有意义,因为接收器必须提供足够的空间来提前接受memcpy
- 数组(如果您简单地声明value[]
形式的变量则不是这种情况) 。那么test v
和malloc
就没有意义了;你可以直接写入引用传递的对象aux
。
答案 1 :(得分:0)
您将v
声明为非指针,这意味着当您在v
中声明时,内存已分配给main
。发送对allocation
的引用仅会正确复制size
,因为它未动态分配。正确的方法是:
声明您的v
为指针
让您allocation
返回test*
(test* allocation()
)
将其分配到v
中的main
。即v = allocate()
然后使用v
像
typedef struct test{
int size;
int value[];
} test;
void allocation(test **v){
test *aux = (test *)malloc(sizeof(test)+3*sizeof(int));
int i;
aux->value[0] = 2;
aux->size = 3;
aux->value[1] = 1;
aux->value[2] = 5;
printf("Teste1 %d\n",aux->size);
for(i=0; i < aux->size; i++){
printf("%d\n", aux->value[i]);
}
*v = aux;
}
void cleanup(test *v){
free(v);
}
int main(int argc, char *argv[]){
test **v;
v = malloc (sizeof (test*));
int i;
allocation(v);
printf("Teste2 %d\n",(*v)->size);
for(i=0; i < (*v)->size; i++){
printf("%d\n", (*v)->value[i]);
}
//cleanup(&v);
return 0;
}
请注意,此后您的清理工作也会发生变化。