2017-01-20 6 views
0

나는 통신을 위해 C로 드라이버를 개발 중이며 교환되는 메시지의 크기는 고정되어 있지 않다. 통신 버스의 권장 사항은 다중 주제에 대한 구조체를 사용하는 것입니다. 이는 또한 제 경우입니다.다른 방법으로 struct hack에서 할당 된 메모리를 수정하는 방법은 무엇입니까?

내 첫 번째 문제 : 새 메시지를 계속 수신해야하며 메시지 데이터를 처리해야하므로 (지연이 발생 함) 새 메시지를 계속 수신해야합니다.

첫 번째 해결 방법 : 데이터를 처리 할 새 메시지가있을 때 스레드를 사용합니다.

두 번째 문제 : 메시지의 데이터에는 구조체의 여러 데이터가있을 수 있으며 통신자는 구조체를 사용하여이 여러 값을 구성해야합니다.

두 번째 해법 : struct 해킹을 사용하여 struct의 메모리 동적 크기를 할당합니다.

현재 문제 : 스레드 또는 함수에 인수로 구조체를 전달할 때 데이터 구조가 손상되어 잘못된 값이 표시됩니다. 만들를

짧은 테스트입니다 : 내가 두 번째 (단 v.size이 바로 값을주고있다)에서 첫 번째 인쇄 잘못된 값을 마우스 오른쪽 값을 가지고이 시험에서

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; 
} 

.

그리고 내 구조체는 테스트에서보다 조금 더 복잡합니다. 내 구조체는 다음과 같습니다.

typedef struct test1{ 
    double v1; 
    double v2; 
} test1; 

typedef struct test2{ 
    int size; 
    test1 values[]; 
} test2; 

수정해야 할 모든 요소가 있으면 해당 함수에서 메모리 구조체를 수정하는 방법을 알고 있습니까? 복수 test2 데이터를 할당 할 수있는 것이 바람직합니다 (필수는 아닙니다).

+0

구조의 끝에 '[]'를 사용하는 것은 _flexible array member_ (FAM)이며 C99 이상에서 완전히 지원된다는 점에 유의하십시오. 'struct hack'은'[] '대신에'[1]'을 사용하며 완전히 지원되지는 않습니다 (일반적으로 FAM이 도입되기 전에 필요했기 때문에 작동하지만 작동 코드에 대한 하위 호환성을 유지해야합니다)). –

답변

0

main에 선언 할 때 v을 비 포인터로 선언하면 메모리가 이미 v에 할당되어 있습니다. allocation에 대한 참조를 보내면 size이 동적으로 할당되지 않기 때문에 올바르게 복사됩니다.

  • allocation 반환 test* (test* allocation())

  • mainv에 할당을 확인 포인터

  • v를 선언 :에이 작업을 수행하는 올바른 방법이 될 것입니다.

편집에 다음에서 포인터와 같은 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; 
    } 
    

    정리 후에도 변경됩니다.

  • +0

    당신의 대답은 정말 테스트를 고칠 수는 있지만, 일단 쓰레드를 만들면 사용할 수 없습니다. 일단 쓰레드를 생성하면 인수로 함수와 구조체 주소를 넘겨 주어야합니다.하지만 여전히이 문제를 인수를 사용하여 해결해야합니다. 다른 해결책을 알고 있습니까? – Caio

    +0

    네, 편집 된 답변에서 작업 코드를 체크 아웃 할 수 있습니다. 당신은 당신의 설정에 따라 약간 조정해야 할 것입니다. – 16tons

    2

    여기서 말하는 것은 불완전한 멤버 int value[]이있는 구조체를 할당하는 것입니다. 원칙적으로 두 개의 구조체를 값으로 복사하는 것이 좋지만 (실제로는 *v = *aux이라고 쓰면 어떻게됩니까?); 그러나, 컴파일러는 어느 크기 멤버 value[]이 런타임시에 취할지를 모르기 때문에, v의 "sizeof"뿐만 아니라 *aux의 크기는 항상 4, 즉 하나의 int 멤버 size의 알려진 크기이다. 따라서이 경우에만 복사되며 value[] - 배열은 단순히 복사되지 않습니다.

    탈출구 이러한 상황이 포인터에 대한 포인터를 필요로 할 (즉 allocation(test **v), 예약 된 메모리가 직접 주에 즉 test *vptr을 테스트 구조체에 대한 포인터를 사용하여 할당 할 수 있도록하고, allocation(&vptr)을 부를 것이다 밖으로.

    값에 대한 참조 대신 값에 경의를 전달할 수 없다면 내용을 전송하는 데 memcpy을 사용해야 할 것입니다.하지만 실제로는 이해가되지 않습니다. 수신기는 사전에 value[] 배열을 취할 수있는 충분한 공간을 제공해야합니다 (단순한 형태의 변수를 test v으로 선언하는 경우에는 해당하지 않습니다). 그 다음에 mallocaux은 의미가 없습니다. 당신은 참조로 전달 된 객체 v에 직접 쓸 수 있습니다.