我是一名學習計算機科學的大四學生,以前從未見過如此奇怪的行為。我確信只有一些我不理解的 C 復雜性,但我現在完全迷失了。
我做了以下功能:
宣言
void parse_resp(unsigned char *resp, unsigned char *chunk, unsigned int *opcode, unsigned char *opparams, unsigned int *nonce, unsigned char *treasure, int *offset);
基本上只是一個函式,我通過一個指標來填充
定義
void parse_resp(unsigned char *resp, unsigned char *chunk, unsigned int *opcode, unsigned char *opparams, unsigned int *nonce, unsigned char *treasure, int *offset)
{
int chunklen = resp[0];
memcpy(&chunk[0], &resp[1], chunklen);
memcpy(opcode, &resp[chunklen 1], 1);
memcpy(&opparams[0], &resp[chunklen 2], 2);
memcpy(nonce, &resp[chunklen 4], 4);
*nonce = htonl(*nonce);
}
變數初始化
unsigned char treasure[1024];
int offset = 0;
unsigned char chunk[127];
unsigned int opcode;
unsigned char opparams[2];
unsigned int nonce;
但這就是奇怪的地方。如果我像這樣呼叫函式parse_resp(buf, chunk, &opcode, opparams, &nonce, NULL, &offset);然后一切正常。但是,如果我將寶藏作為引數傳遞(即使 parse_resp 不使用寶藏),那么它就不起作用 memcpy(opcode, &resp[chunklen 1], 1);。在此之后列印操作碼的值會顯示一些隨機 int 。這對我來說毫無意義。我不明白將寶藏作為引數傳遞如何使 memcpy 行為不正確。如果我列印 的值resp[chunklen 1],我會看到一個 0(如預期的那樣),但是當我嘗試到memcpy()同一個位置時,我會得到一個亂數?知道這里發生了什么嗎?
注意:我意識到這個錯誤有相當簡單的解決方法,但我想先了解發生了什么。
uj5u.com熱心網友回復:
opcode具有int最有可能是 4 個位元組的型別,但是您只是將一個位元組復制到其中:
memcpy(opcode, &resp[chunklen 1], 1);
所以其他 3 個位元組未初始化,因此具有不確定的值。因此,充其量不能保證這些位元組具有任何特定值,并且更改parse_resp呼叫方式足以改變那些未初始化位元組的值。
在某些情況下,讀取未初始化的變數可能會觸發未定義的行為,但是由于opcode已獲取其地址,這不是問題(除非您使用的是具有陷阱表示的奇異架構int)。
將此變數的型別和相關引數更改為unsigned char。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/440249.html
標籤:C
上一篇:簡單的讀取操作不從char設備linux讀取任何東西
下一篇:如何讓執行緒等待變數更改?
