如何以不同的方法修复从 struct hack 分配的内存?
How to fix allocated memory from a struct hack in a different method?
我正在用 C 语言开发用于通信的驱动程序,并且交换的消息没有固定大小。 communication bus推荐多topic使用struct,我也是这样。
我的第一个问题:我必须不断收听新消息,当我收到一条消息时,我必须处理消息数据(它有延迟)并仍在收听新消息。
方案一:获取新消息时使用线程处理数据
我的第二个问题:消息中的数据可以有一个结构的多个数据,而我的通信器需要使用一个结构来组织这些多个值。
第二个解决方案:使用 struct hack 分配内存动态大小的结构。
我当前的问题:当我将我的结构作为参数传递给线程或任何函数时,我丢失了数据结构并得到了错误的值。
一个简短的测试是:
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
数据是可取的(不是必需的)。
您将 v
声明为 non-pointer,这意味着当您在 main
中声明时,内存已经分配给 v
。发送对 allocation
的引用只会正确复制 size
,因为它不是动态分配的。正确的做法是:
将您的 v
声明为指针
让你的allocation
returntest*
(test* allocation()
)
分配给main
中的v
。即类似 v = allocate()
并从那时起像指针一样使用v
编辑:由于 OP 希望它仅作为参数工作,因此最好的方法是使用双指针。检查以下代码:
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;
}
请注意,在此之后您的清理工作也会发生变化。
这里的问题是你分配了不完整成员的结构int value[]
;虽然按值复制两个结构原则上是可以的(如果你写 *v = *aux
实际上会发生这种情况);但是,由于编译器不知道 value[]
将在运行时采用哪个大小成员,因此 v
的 "sizeof" 以及 *aux
的大小始终为 4,即一个 int 成员的已知大小 size
。因此,只有 this 被复制,而 value[]
-array 根本没有被复制。
解决这种情况的方法是需要一个指向指针的指针(即allocation(test **v)
,这样保留的内存可以直接分配给它,使用指向 main 中的结构测试的指针,即 test *vptr
,然后调用 allocation(&vptr)
.
如果您无法避免传递对值的尊重(而不是对值指针的引用),我想您将不得不使用 memcpy
来传输内容。但这实际上没有意义,因为接收者必须提供足够的 space 来提前接收 value[]
-数组(如果您简单地声明一个形式为 [= 的变量,情况就不是这样了) 22=]).那么 malloc
和 aux
就没有意义了;您可以直接写入通过引用传递的对象 v
。
我正在用 C 语言开发用于通信的驱动程序,并且交换的消息没有固定大小。 communication bus推荐多topic使用struct,我也是这样。
我的第一个问题:我必须不断收听新消息,当我收到一条消息时,我必须处理消息数据(它有延迟)并仍在收听新消息。
方案一:获取新消息时使用线程处理数据
我的第二个问题:消息中的数据可以有一个结构的多个数据,而我的通信器需要使用一个结构来组织这些多个值。
第二个解决方案:使用 struct hack 分配内存动态大小的结构。
我当前的问题:当我将我的结构作为参数传递给线程或任何函数时,我丢失了数据结构并得到了错误的值。
一个简短的测试是:
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
数据是可取的(不是必需的)。
您将 v
声明为 non-pointer,这意味着当您在 main
中声明时,内存已经分配给 v
。发送对 allocation
的引用只会正确复制 size
,因为它不是动态分配的。正确的做法是:
将您的
v
声明为指针让你的
allocation
returntest*
(test* allocation()
)分配给
main
中的v
。即类似v = allocate()
并从那时起像指针一样使用
v
编辑:由于 OP 希望它仅作为参数工作,因此最好的方法是使用双指针。检查以下代码:
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;
}
请注意,在此之后您的清理工作也会发生变化。
这里的问题是你分配了不完整成员的结构int value[]
;虽然按值复制两个结构原则上是可以的(如果你写 *v = *aux
实际上会发生这种情况);但是,由于编译器不知道 value[]
将在运行时采用哪个大小成员,因此 v
的 "sizeof" 以及 *aux
的大小始终为 4,即一个 int 成员的已知大小 size
。因此,只有 this 被复制,而 value[]
-array 根本没有被复制。
解决这种情况的方法是需要一个指向指针的指针(即allocation(test **v)
,这样保留的内存可以直接分配给它,使用指向 main 中的结构测试的指针,即 test *vptr
,然后调用 allocation(&vptr)
.
如果您无法避免传递对值的尊重(而不是对值指针的引用),我想您将不得不使用 memcpy
来传输内容。但这实际上没有意义,因为接收者必须提供足够的 space 来提前接收 value[]
-数组(如果您简单地声明一个形式为 [= 的变量,情况就不是这样了) 22=]).那么 malloc
和 aux
就没有意义了;您可以直接写入通过引用传递的对象 v
。