2014-03-28 5 views
0

C로 작성된 특정 응용 프로그램에서 메모리가 효율적이어야합니다. 통계를 수집하고 있으므로 메모리 소비를 최소화하기 위해 런타임에 특정 필드를 "켜고 끌 수"있어야합니다. 매크로를 사용하여 조건부 구조체 필드를 정의 할 수 있다는 것을 알고 있지만 실수가 아닌 경우 컴파일 타임입니다. 런타임시 C에서이 작업을 수행 할 수 있습니까?C에서 구조체의 런타임 조건부 필드

예 :

입력 :

collect (A,B) 

이런 구조체 될 것이다

struct statistics{ 
double A; 
double B; 
}; 

하지만 입력 :

collect (A,B,C) 

같은 구조체가 발생할 것 this :

struct statistics{ 
double A; 
double B; 
double C; 
}; 
+1

동적 할당 및 구조를 사용해야합니다. – OldProgrammer

+1

그 경우 struct가 아닌 각 레코드에 대해 동적 크기의 배열을 사용하는 것이 좋습니다 (모든 필드가 동일한 유형, 즉 'double'입니까?). 또는 AoS에서 SoA로 전환 할 수 있습니다. 각 배열은 포인터이며 필요한 경우에만 할당됩니다. –

+0

오른쪽, (그들은 모두 두 배가 아니지만 대부분 두 배와 정수입니다); 그러나 포인터는 4 바이트 자체이므로이 필드 각각 대신 포인터를 할당 할 수도 있고 할당하지 않을 수도 있습니다. 그러나 여전히 메모리의 동일한 순서를 중심으로합니다. 그것보다 더 잘할 수 있습니까? – user2662165

답변

1

런타임 중에 구조체 내의 특정 필드를 끌 수 없습니다. 그러나 여러 필드를 나타낼 수있는 동적으로 할당 된 double 배열을 가리키는 포인터가있을 수 있습니다.

#include <stdio.h> 
#include <stdlib.h> 

struct stats 
{ 
    size_t number_of_doubles; 
    double* data; 
}; 

void make_stats(struct stats* pStats) 
{ 
    pStats->number_of_doubles = 3; 
    pStats->data = (double*) malloc(pStats->number_of_doubles * sizeof(double)); 
} 

void delete_stats(struct stats* pStats) 
{ 
    free(pStats->data); 
} 

int main() 
{ 
    struct stats foo; 

    make_stats(&foo); 

    foo.data[0] = 3.0; 
    foo.data[1] = 5.0; 
    foo.data[2] = 7.0; 

    delete_stats(&foo);  
    return 0; 
} 
+0

고마워! 이게 작동 할 것 같아요. number_of_doubles를 특정 통계의 존재 또는 존재 여부에 대한 일종의 플래그로 변경해야합니다.하지만이 방법이 효과가 있다고 생각합니다. – user2662165

+0

당신을 진심으로 환영합니다. 나는 당신이 밖으로 시도하고 삭제 메인 추가했습니다. 이것이 당신에게 도움이 되었다면 답변을드립니다 : – csnate

0

대신 구조체의 일반적인 배열 (의 AoS) :

struct statistics{ 
    double A; 
    double B; 
    double C; 
}; 

struct statistics my_statistics = malloc(1000000 * sizeof(my_statistics[0])); 

my_statistics[0].A = 1; 
my_statistics[0].B = 2; 
my_statistics[0].C = 3; 

당신이 배열의 구조체에 (SOA)를 전환 할 수 있습니다 :

struct statistics{ 
    double *A; 
    double *B; 
    double *C; 
}; 

struct statistics my_statistics; 

my_statistics.A = using_A ? malloc(1000000 * sizeof(my_statistics.A[0])) : NULL; 
my_statistics.B = using_B ? malloc(1000000 * sizeof(my_statistics.B[0])) : NULL; 
my_statistics.C = using_C ? malloc(1000000 * sizeof(my_statistics.C[0])) : NULL; 

my_statistics.A[0] = 1; 
my_statistics.B[0] = 2; 
my_statistics.C[0] = 3; 
+0

시위를 가져 주셔서 감사합니다! 수집 된 통계의 수가 100을 넘어서는 것을 고려하면, 이것은 적어도 4 바이트 * 100 크기 구조체를 여전히 가질 것입니다. – user2662165

+0

물론 - 수집하는 데이터의 양과 메모리 제약 조건을 모르기 때문에 최적의 솔루션을 제공하는 것이 쉽지 않습니다. 메모리가 정말로 빡빡하다면 역동적 인 크기의 배열을 사용하십시오 - 오버 헤드는 약간 적지 만 가격은 개별 요소에 대한보다 복잡한 액세스입니다. –

+0

@ user2662165 : PS : AoS 사례에 위 구조체의 인스턴스가 하나만 있다는 것을 알고 계십니까? –

0

이 있습니다 예를 들어 런타임시 구조체의 크기를 변경할 수있는 방법이 없습니다. 구조체의 크기는 스택이나 힙에 할당 할 때마다 실행 파일의 명령어에 내장됩니다. 또 다른 예로 struct의 sizeof을 컴파일 할 때 사용할 수 있으므로 런타임에 변경할 수 없습니다.

물론 사용자 정의 메모리 관리자를 사용하여 사용자 정의 구조체를 만들 수 있지만 언어에 내장되어 있지는 않습니다.