如何使用不同的方法修复struct hack中的已分配内存?

时间:2017-01-20 13:09:20

标签: c struct dynamic-allocation

我正在用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数据,这是可取的(不是必需的)。

2 个答案:

答案 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 vmalloc就没有意义了;你可以直接写入引用传递的对象aux

答案 1 :(得分:0)

您将v声明为非指针,这意味着当您在v中声明时,内存已分配给main。发送对allocation的引用仅会正确复制size,因为它未动态分配。正确的方法是:

  • 声明您的v为指针

  • 让您allocation返回test*test* allocation()

  • 将其分配到v中的main。即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;
}

请注意,此后您的清理工作也会发生变化。