2013-07-18 3 views
0

일부 exsiting 코드에서 찾았지만 문제가 생겼다. 코드가 제대로 작동하면 코드 조각에 이상한 점이 있으면이 코드를 사용하면 도움이 될 수 있습니까?포장 된 구조체 크기가 C입니까?

구조체의 크기를 계산할 때 2를 무시하는 이유는 무엇입니까? ?

 tmsg_sz = sizeof(plfm_xml_header_t) + sizeof(oid_t) + sizeof(char*) 
      + sizeof(unsigned) + sizeof(snmp_varbind_t)*5 ; 
     tmsg = (snmp_trap_t*) malloc(tmsg_sz); 
     if (!tmsg) { 
      PRINTF("malloc failed \n"); 
      free(trap_msg); 
      return -1; 
     } 
     memset (tmsg, 0, tmsg_sz); 
     tmsg->hdr.type = PLFM_SNMPTRAP_MSG; 
     copy_oid_oidt(clog_msg_gen_notif_oid, OID_LENGTH(clog_msg_gen_notif_oid), &tmsg->oid); 
     tmsg->trap_type = SNMP_TRAP_ENTERPRISESPECIFIC; 
     tmsg->trap_specific = 1; 
     tmsg->trapmsg = strdup("Trap Message"); 
     tmsg->numofvar = 5; 
     build_snmp_varbind(&(tmsg->vars[0]), facility, STR_DATA_TYPE, sizeof(facility)+1, clog_hist_facility_oid, 14); 

     build_snmp_varbind(&(tmsg->vars[1]), &sev, U32_DATA_TYPE, sizeof(sev),clog_hist_severity_oid, 14); 

     build_snmp_varbind(&(tmsg->vars[2]), name, STR_DATA_TYPE, sizeof(name)+1, clog_hist_msgname_oid, 14); 

     build_snmp_varbind(&(tmsg->vars[3]), trap_msg, STR_DATA_TYPE, strlen(trap_msg)+1,clog_hist_msgtext_oid, 14); 

     // get system uptime 
     long uptime = get_uptime(); 
     build_snmp_varbind(&(tmsg->vars[4]), (long*)&uptime, TMR_DATA_TYPE, sizeof(uptime),clog_hist_timestamp_oid, 14); 



    typedef struct snmp_trap_s { 
     plfm_xml_header_t hdr; 
     oid_t    oid;  /* trap oid */ 
     unsigned   trap_type; 
     unsigned   trap_specific; 
     char    *trapmsg; /* text message for this trap */ 
     unsigned   numofvar; 
     snmp_varbind_t vars[0]; 
    } __attribute__((__packed__)) snmp_trap_t; 
+0

"구조체의 크기를 계산할 때 두 개의 부호가 무시되는 이유는 무엇입니까?" 응? –

+0

@Judeyou 이것은 데이터 구조를 묶는 한 가지 방법입니다. GCC와 같은 모양입니다. 다른 컴파일러는 예를 들어 #pragma pack (1)을 사용합니다. 여기에 뭐가 잘못됐다고 생각하니? –

+0

이것은 이상하게 보입니다. 나는 그 크기가'sizeof (snmp_trap_s)'로 계산 될 것이라고 생각했을 것이다. – STLDeveloper

답변

0

컴파일러는 여러 가지 방법으로 정렬 된 멀티 바이트 데이터를 저장하려고 노력합니다. 예를 들어 sizeof int == 44으로 나눌 수있는 위치에 배치되어야 할 수도있는 아키텍처의 int 변수입니다. 이것은 어려운 요구 사항 일 수 있으며, 시스템을보다 효율적으로 만들 수 있습니다. 컴퓨터에 따라 다릅니다. 그래서, 아키텍처에 따라

typedef struct combo { 
    char c; 
    int i; 
} combo; 

을 고려 sizeof combo 5, 6, 또는 가장 자주 8. 스왑 두 멤버가 될 수 있으며, 크기는 그러나 5

typedef struct combo2 { 
    int i; 
    char c; 
} combo2; 

, 배열해야한다 combo2 S는 크기를 가질 수 당신은 기대하지 않는다 : 낭비되는 공간의 3 바이트는을 따를

combo2 cb[2]; 

cb의 크기는 아주 잘, 16 일 수및 combo2[1]. 이렇게하면 combo2[1].i이 4로 나눌 수있는 위치에서 시작할 수 있습니다.

구조체의 멤버를 크기별로 정렬하는 것이 좋습니다. 8 바이트 멤버는 4 바이트 멤버보다 먼저, 2 바이트 멤버보다 1 바이트 멤버보다 먼저 나와야합니다. 물론 일반적인 크기를 알고 있어야하며 문자가 큰 단어로 묶여 있지 않은 괴상한 구조로 작업 할 수는 없습니다. 크레이? 기침 - 기침.

+0

@Peter L. 구조체의 크기를 의미하며, 계산시 부호없는 2자를 생략 할 수 있습니다. – Judeyou