2011-11-18 3 views
0

구조체에 저장되는 const char 배열에 문제가 있습니다. 구조체의 값을 호출 할 때 항상 예상 값을 얻지 못합니다. 다음은 구조체에 const char 배열을 올바르게 할당하는 방법은 무엇입니까?

코드입니다 :

typedef struct 
{ 
    char *update_type; 
    char *transaction; 
} TickType; 

스레드에서 내가 가진 :

const char tx_types[] = "INV/ADD/MOD/DEL/RPL"; 
const char upd_types[] = "INS/OVR/MOV/DEL"; 

tick->transaction = &tx_types[4*upd.xpbu_transaction_type]; 
tick->update_type = &upd_types[4*upd.xpbu_update_type]; 

upd.xpbu_transaction_typeupd.xpbu_update_type 반환의 int (0-4) 및 (0-3)이다. 다른 스레드에서 우리는 파일에 인쇄가 있습니다

fprintf(out, "%3.3s/%3.3s:\n",tick->transaction, tick->update_type); 
fflush(out); 

다음 내가 볼 출력 파일 체크 아웃 할 때 문제가 : 당신이 단지 바로 때때로 볼 수 있습니다 그래서

+MOD/DEL: 
+ /Â +: 
+MOD/DEL: 
+MOD/ : 
    /@Ea: 
    /<90>Ea: 
    /Ã Ea: 
    /0Fa: 
    / : 

합니다.

실수가 구조 지정에 있다고 확신합니다. 불행히도 독점 소프트웨어이기 때문에 코드를 더 자세히 볼 수는 없습니다.

+0

, 무엇이 어디서 잘못되는지 보려면 어떻게해야합니까? –

+0

여기서 문법과 철자에 표시되는 것보다 코드에 더 많은주의를 기울 이셨기를 바랍니다. – Indy9000

+0

gdb가 설치되지 않은 상태에서 하나의 특정 Linux 상자 만 실행할 수 있기 때문에 디버거를 단계적으로 실행할 수 없습니다. xpbu_transaction_type 및 xpbu_update_type은 전역입니다. 그들은 소유권 API에서 가져온 것입니다. – Nathan

답변

1

문제점은 배열의 정의를 어디에 두는 지 의심 스럽습니다.

작업 사이의 문자열에 주소를 공유하려면 전역 주소 공간에 배치하거나 어딘가에 정적으로 선언해야합니다.

또는 BlackBear가 메모리를 할당하고 거기에 하위 문자열을 복사하는 것이 좋습니다.

+0

이것은 당신이 지금 정적 char 배열'ty_types [] = "INV/ADD/MOD/DEL/RPL"; 정적 문자 upd_types [] = "INS/OVR/MOV/DEL"; – Nathan

0

strcpy를 사용하여 update_type과 트랜잭션을 malloc하고 중요한 부분을 복사해야합니다. "INV \ x00ADD \ x00MOD \ x00DEL \ x00RPL"과 "INS \ x00OVR \ x00MOV \ x00DEL"을 조금 편집해야합니다.

+0

아니요,'fprintf ("% 3.3s")'의 사용은 널 종료자를 필요로하지 않습니다. – aschepler

+0

@aschepler :하지만 strcpy 않습니다 – BlackBear

1

우선 tick은 스레드간에 공유됩니까? 그렇다면 중요한 섹션에서 멤버에게 할당을 보호해야합니다. 그렇지 않으면 변수가 인쇄되고 다른 스레드가이를 업데이트하여 인쇄 중에 쓰레기를 일으킬 수 있습니다. fprintf()fflush()의 스레드 안전성에 대해 잘 모르겠습니다. 영향을 미치는 또 다른 요소 일 수 있으므로 알아 두어야합니다.

0

코드에서 upd.xpbu_transaction_type 또는 upd.xpbu_update_type이 적절한 범위 내에 있는지 확인하지 않습니다.

또한 스레드 안전을 위해 뮤텍스 또는 무언가를 사용해야합니다.

또한 이러한 문자열이 실제로 저장되는 메모리 영역이 명확하지 않은 경우도 있습니다. 환경에 따라 const 문자열의 위치가 다른 규칙이 있습니다. 두 스레드가 항상 액세스 할 수있는 전역 메모리에 있는지 확인하십시오. 이를 보장하는 가장 쉬운 방법은 문자열을 const 밖에서 모든 함수 외부에 정의하는 것입니다. 함수에 있어야한다면 static const로 선언해야합니다.

환경 뭔가에 따라이 같은 간단 충분할 것이다 :

스레드 A를 :

/* validate upd values, etc*/ 
switch (upd.xpbu_transaction_type) 
{ 
... 
default: 
    xpbu_tt = 0; 
} 

... 
taskLock(); 
tick->transaction = &tx_types[4*xpbu_tt]; 
tick->update_type = &upd_types[4*xpbu_ut]; 
taskUnlock(); 

스레드 B :

디버거에서 관련 부분을 단계별로 할 수
While (1) 
{ 
... 
taskLock(); 
t = tick->transaction; 
u = tick->update_type; 
taskUnlock(); 
fprintf(out, "%3.3s/%3.3s:\n",t,u); 
fflush(out); 
} 
관련 문제