2012-05-24 538 views
1

我正在製作一個程序來構建二進制消息。我使用char字符串來保存二進制值。所以我已經初始化了一堆具有默認值的char字符串。然後我通過運行for循環將它們結合起來,並將它們讀入一個大字符串(aismsg/ais_packet)中。並且一切正常,直到我添加msg14Text [],然後我建立的字符串(aismsg/ais_packet)被縮短,如下所示(即使我沒有使用變量)。看起來像我添加msg14Text []時,它改變了其他字符串之一的值。這可能是內存分配問題嗎?代碼的字符串覆蓋其他字符串

部分:

char ais_packet[257];       //Allokerer array for ais data pakke. 
char aismsg[175];        //Allokerer array for meldingen. 
int burst_nr = 1;        //Indicates with burst it is transmittin (1-7). 

char ramp_up[] = "00000000";     //Ramp up buffer. 
char train_seq[] = "010101010101010101010101"; //Training sequence 24 bits of alternating 0-1.s 
char hdlc_flag[] = "01111110";     //HDLC Start and END flag. 
char buffer[] = "000000000000000000000000";  //Data packet buffer. 
char msgID1[] = "000001";      //msg. 1. 
char msgID14[] ="010100";      //msg. 14. 
char repeat[] = "00";       //repetert 0 ganger. 
char mmsi[] = "000111010110111100110100010101"; //Gir 123456789 som MMSI. 
char nav_stat[] = "1111";      //Gir 15= AIS-SART test, endres til 14 (1110) for aktiv AIS-SART.x' 
char rot[] = "10000000";      //Rate of Turn -128 betyr ikkje tilgjengelig. 
char sogBin[] = "1111111111";     //Tilsvarer 1023 = not available = default. 
char pos_acc[] = "0";       //Posisjonsnøyaktighet over 10m. 1 = under 10m. 
char lonBin[] = "0110011110010001101011000000"; // Tilsvarer 181 grader som er default verdi for Longitude. 
char latBin[] = "011010000010010000101000000"; // Tilsvarer 91 grader som er default verdi for Latitude. 
char cogBin[] = "111000010000";     //Tilsvarer 3600 = not available = default. 
char headingBin[] = "111111111";    //511 = not available = default 
char timestamp[] = "111100";     //Tid siden melding er generert, 60 = default = ts not available. 
char spec_man[] = "01";       //Special manouver 0 = default, 1 = not engaged in special manouver 
char spare[] = "000"; 
char spareMSG14[] = "00";       //Reserved. 
char raim[] = "0";        //RAIM 0 = not in use. 
char comm_state[] = "00011100000000000000";  // First 2bit: Sync state: 3 = no UTC sync = default, 0 = UTC sync. 0011100000000000000 
char msg14Text[] = "100100101101111011111100"; //CAUSING TROUBLE!!!! for AIS melding 14 står "Test" med 6-bit ASCII koding. 

該函數的enitre代碼可以在pastebin.com/wj0RxyLX

輸出AIS的分組中找到與msg14Text []:

00000000 

AIS的輸出沒有msg14Text []的數據包:

0000000001010101010101010101010101111110000001000001110101101111001101000101011111100000000011010000000000000110100011000101111000000101100100000100001100101110000100000000110011111000100000011100000000000000001000100110100101111110000000000000000000000000 

aispacket應包括以下變量:

ramp_up[] + train_seq[] + hdlc_flag[] + Datapacket(168bit) + crc(16bit) + hdlc_flag[] + buffer[] + '\0' 
+2

Pleae創建一個[簡短自包含的測試用例](http://sscce.org),並將其粘貼到您的問題中。 –

+1

爲什麼您將_strings_用於_binary_數據有特殊原因嗎? – JimmyB

回答

1

「這可能是內存分配的問題?」

您沒有在代碼中明確分配任何內存。請注意,char repeat[] = "00";是靜態分配的數組,其大小等於3 char s,其內容正在通過字符串文字"00"進行初始化。

問題是最有可能在這些字符串複製到ais_packet因爲你這樣做,在非標準的方式(逐字符),這將導致你的代碼難以閱讀,它很容易犯一個錯誤有:

for(int k=0; k<256; k++) 
{ 
    ... 
    if(k==256) // are you sure that value of k will reach 256 ? 

我建議你使用已經爲此創建C風格的功能:通過使用strcpy通過複製第一串進去了解創建ais_packet並保留通過使用strcat追加其他字符串擴展該ais_packet的內容。

這個問題也將幫助你:Using strcat in C

1

在醜陋for (k=0; k < 168; k++) { if ... else if ...}循環結束

else if(k==168) 
     { 
     aismsg[k] = '\0'; 
     k=0; 
     } 

這將使要麼(K < = 168)的循環運行裏永恆,要麼(K < 168)從未被執行。 (有這種模式的多個實例)

BTW另一種方式做同樣的(也更快)將

.... 
unsigned dst=0; 
memcpy (array+dst, src1, 123); 
dst += 123; 
memcpy(array+dst, src2, 234); 
dst += 234; 
... 
array[dst] = 0; 
0

只是一個想法,但如果你正在構建二進制消息,爲什麼不使用實際的二進制而不是char數組?這裏有一種使用聯合內的結構來位二進制數據的方法。

// declaration 
typedef union 
{ 
    uint32_t packed; 
    struct { 
     uint16_t sample1: 12; // 12 bits long 
     uint16_t sample2: 14; 
      uint16_t 6;   // unused bits 
    } data; 
} u1; 

// instantiation 
u1 pack1; 

// setting 
pack1.data.sample1 = 1234; 
//getting 
uint16_t newval = pack1.data.sample2; 
// setting bit 6 in sample 1 
pack1.data.sample1 |= (1 << 6); 
// setting lo nibble in sample1 to 0101 
pack1.data.sample1 &= 0b11110101; 
// getting the whole packed value 
uint32_t binmsg = pack1.packed;