2012-05-09 67 views
0

我試圖將memcpy measure_msg(struct test)寫入緩衝區。但是,下面的代碼似乎沒有複製數據。價值回報memcpy結構失敗

**** ptr:0xb781c238 
**** ptr:0xb781c23c 
**** ptr:0xb781c244 
buff[0]=5 - buff[1]=0 - buff[2]=0 - buff[3]=0 - buff[4]=W - buff[5]= - buff[6]= - buff[7]= - buff[8]= - buff[9]= - buff[10]= - buff[11]= - 

這段代碼出了什麼問題?

struct test{ 
    int mode; 
    int id; 
}; 

int func() 
{ 
int i, size; 
struct test measure_msg; 
char buff[20]; 
char* ptr;  

memset(&measure_msg, 0x00, sizeof(struct test)); 

ptr = buff; 
fprintf(stderr, "**** ptr:%p\n", ptr); 
sprintf(ptr, "%02d%02d", 50, 0); 
ptr += 4; 
size = 4; 
size += sizeof(struct test); 

fprintf(stderr, "**** ptr:%p\n", ptr); 

measure_msg.id = 9999; 
measure_msg.mode = 1111; 

memcpy(ptr, &measure_msg, sizeof(struct test)); 
ptr += sizeof(struct test); 

fprintf(stderr, "**** ptr:%p\n", ptr); 

for (i=0; i<size; i++){ 
    fprintf(stderr, "buff[%d]=%c - ", i, buff[i]); 
} 

return 0; 
} 
+0

沒有它似乎工作?你期望它打印什麼? – moooeeeep

回答

1

你正在做的事情很奇怪,但,看看這個:

sprintf(ptr, "%02d%02d", 50, 0); 

你會寫一個你的緩衝區。現在buf將包含「5000」。請注意,它不包含值50和0,但它們的字符串表示

現在,當您將緩衝區複製到結構中時,您將其字段設置爲這四個字節,但它們不是打印字符串時看到的字符,而是它的ASCII碼。請注意,在這條線:

fprintf(stderr, "buff[%d]=%c - ", i, buff[i]); 

您打印緩衝區的字符的內容,「5」被存儲爲0x35(十進制53),那麼這將是你的結構的第一個字節的內容(等等)。

如果這真的是你想要做的事情,那麼你的代碼是確切的(但你用指針玩得太多,是否只是一個測試?),但它真的很奇怪,否則你走錯了方向做你需要的。

0

的的memcpy()調用的工作我的系統(GCC/MinGW的系統,Windows)上的所有權利。你沒有得到正確的輸出,因爲一些被複制到buff中的「字符」是不可打印的。

嘗試

fprintf (stderr, "buff[%d]=%x - ", i, buff[i]); 

代替。

的數據將被存儲爲

buff [0] = 0x35 /* ASCII for '5' */ 
buff [1] = 0x30 /* ASCII for '0' */ 
buff [2] = 0x30 
buff [3] = 0x30 
buff [4] = 0x57 /* as 1111 is 0x00000457 in hex */ 
buff [5] = 0x04 /* stored in little endian convention */ 
buff [6] = 0x00 /* and here size of int = 4 */ 
buff [7] = 0x00 
buff [8] = 0x0F /* as 9999 is 0x0000270F in hex */ 
buff [9] = 0x27 
buff [10] = 0x00 
buff [11] = 0x00 

但什麼是你想無論如何做,通過複製結構來字符數組?

+0

請注意,不同系統的輸出會有所不同。使用英特爾架構的系統採用「小端」規則來存儲數字,這意味着最低有效字節(例如0x00000457中的0x57)將首先存儲,最高有效字節將最後存儲。而且,在GCC中,int數據類型的大小是4,而其他編譯器可能不會這樣。 –

0

當您memcpy您的measure_msgbuff您正在複製int類型的值。之後,您正在打印字符類型值。一個int類型的值由4個字節組成,可能沒有打印表示形式:即33752069 int值,0x02030405十六進制格式,有4個字節,一旦打印出來就像字符一樣,你得到0x02,0x03,0x04和0x05 char值。

更改打印MASC使用int類型和投各buff[i]爲int和你的價值觀將被打印。

fprintf(stderr, "buff[%d]=%d - ", i, (int)buff[i])